Good day everyone. I’m currently facing a problem with saving a meshes as a babylon file.
Right now, I have done the following:
- I have a model of a lion with panels, the panels are detachable from the lion’s body and can be designed with flowers (which are really planes with materials/ diffuse texture set on it). What I do is I clone the flower on the book when it is clicked using mesh.clone(cloneName) method. See image below:
- What I do is after placement of flower on the panel, the user can choose to save his current progress. There is no problem with I place unique flowers on each panel like the image below:
With the above sample, I encounter no problem when saving it and importing it to the scene on reload.
- I only encounter the error when I design a panel with duplicated of one type of flower clicked like in the image below:
This is how I save the designed panel / serialize the meshes:
function save_designed_panels(filename) {
designCamera.detachControl(canvas);
var serializedMesh;
//the mapping of the panel:flowers will be saved here
let savedFlowersList = {};
//mapping of the serialized mesh will be saved here
var meshes_to_save = {                       
    "materials": [],                        
    "geometries":    {    
        "boxes":[],                                            
        "spheres":[],                                            
        "cylinders":[],                                            
        "toruses":[],                                            
        "grounds":[],                                            
        "planes":[],                                            
        "torusKnots":[],                                            
        "vertexData":[]                        
    },                        
    "meshes": []            
};  
if(objectUrl) {
    window.URL.revokeObjectURL(objectUrl);
}
//for each flower mesh placed in each panel taken from the flowerspanelsmap, serialize each mesh
for (const [panel,val] of flowersPanelsMap.entries()) {
    if(val.size>0){
        serializedMesh = BABYLON.SceneSerializer.SerializeMesh(panel,false,true);    
        for (let i=0;i<serializedMesh["meshes"].length;i++) { 
            meshes_to_save["materials"].push(serializedMesh["materials"][i]);            
            meshes_to_save["geometries"]["vertexData"].push(serializedMesh["geometries"]["vertexData"][i]);   
            meshes_to_save["meshes"].push(serializedMesh["meshes"][i]);  
        } 
    }
}
//for each flower mesh placed in each panel taken from the flowerspanelsmap, serialize each mesh
//the modified_panels_list contains the panels:flowers mapping taken from the database, only update the flowers in the db with updated flowers
for (const [panel,val] of flowersPanelsMap.entries()) {
    if(modified_panels_list.has(panel.name)){
        let temp = [];
       
            for(const a of val.values()){
                temp.push(a.name);
            }
      
        if(temp.length == 0) temp = "0";
        
       savedFlowersList[panel.name] = temp;
    }
}
//convert the meshes to blob format and save as babylon file
var strMesh = JSON.stringify(meshes_to_save);
var blob = new Blob ( [ strMesh ], { type : "octet/stream" } );
if (filename.toLowerCase().lastIndexOf(".babylon") !== filename.length - 8 || filename.length < 9){
    filename += ".babylon";
}
//post to backend to save the user's progress
if(blob){
    $.ajax({
        type: "POST",
        url:urlDesignPanel,
        data:{
            uid: userId,
            designPath:userId+"_designedPanel.babylon",
            babylonFile:strMesh,
            flowersList:savedFlowersList,
            _token:token
        },
        success: function(result){
            Swal.fire({
                width: '10vw',
                padding: '3em',
                background: 'rgba(8, 64, 147, 0.6) url(front/images3D/designScene/trevorSaved.png)',
                title: '\n\n\n\nYour progress has been saved.',
                showConfirmButton: false,
                position: 'top-end',
                timer: 3000,
                customClass: {
                  popup: 'trevor-popup-class',
                }
              });
        
            designCamera.attachControl(canvas,true);
            savedFlowersList = {};
            is_design_saved = true;
        },
        error: function(result){
            Swal.fire({
                width: '10vw',
                padding: '3em',
                background: 'rgba(8, 64, 147, 0.6) url(front/images3D/designScene/trevorSaved.png) ',
                title: '\n\n\n\nOops...something went wrong. Your progress was not saved.',
                showConfirmButton: false,
                position: 'top-end',
                timer: 3000,
                customClass: {
                    title: 'error-title-class',
                    popup: 'trevor-popup-class',
                },
            });
        }
    });
}     
}
And this is how I import the panels on page access:
function load_saved_game(){
Promise.all([
    BABYLON.SceneLoader.ImportMeshAsync(null, "storage/saveState/designPanel/", load_filename, designScene).then(function (result) {
      
        result.meshes.forEach(function(m){
            if(mbayePanelsMap.has(m.name)){
                m.setParent(mbayeDesign_object);
                //mbayePanelsMap is a fresh mapping of the panels:flowers loaded from the database when the page is loaded
                if(mbayePanelsMap.get(m.name) !== null)  mbayePanelsMap.get(m.name).dispose();
                m.isPickable = true;
                m.material.emissiveColor = new BABYLON.Color3(0,0,0);
                mbayePanelsMap.set(m.name, m);
               
               
                let children = set_panel_children(m._children);
                flowersPanelsMap.set(m, children);
            }
        });
     
    }),
    
]).then(() => {
    isProgressLoaded = true;
});
}
And this is the error I am getting when I load the page when I have previously designed a panel with flowers of the same type.
I am not sure why I am getting this error and I also tried loading the exported babylon file in sandbox and it throws me error that id is null. Please guide me where I am doing wrong. Thank you.
Page load error:

Sandbox error:
For reference, this is how I clone the black flower from the book. onPointerDown, I call this function:
function create_black_flower_copy(theFlower){
//create a clone of the flower clicked
let theFlowerCopy = theFlower.clone(theFlower.name);
theFlowerCopy.material = theFlower.material.clone(theFlower.name+flowerCtr+“Matl”);
theFlowerCopy.material.id = theFlowerCopy.material.name;
//i have also tried createInstance but it behaves differently 
// let theFlowerCopy = theFlower.createInstance(theFlower.name + flowerCtr);
// theFlowerCopy.setParent(theFlowerCopy.parent)
flowerCtr++;
let flowerHasParent = false;
theFlowerCopy.id = theFlowerCopy.id + "_"+theFlowerCopy.uniqueId;
;
//if the active camera is panel camera or focus camera
if(designScene.activeCamera === panelCamera ){
    if(theFlower.parent === bookLeftPages) flowerHasParent = true;
}else{
    if(theFlower.parent === bookLeftPages) flowerHasParent = true;
}
//if the clone has a parent, set position x and y depending if the camera is panel or focus
if(flowerHasParent){                        //if focus camera
    theFlowerCopy.position.y += 50;
    theFlowerCopy.position.x -= 50;
    theFlowerCopy.rotation = new BABYLON.Vector3(BABYLON.Tools.ToRadians(155),BABYLON.Tools.ToRadians(0),BABYLON.Tools.ToRadians(0));
    theFlowerCopy.setParent(null);
    
}else{          
    theFlowerCopy.position.y += 2.5;
    theFlowerCopy.position.x += 0.1;
}
  
//increment the current flower selection count
flowerSelectionCount++;
if(theCurrentFlower.obj) theCurrentFlower.obj.showBoundingBox = false;
//attach the position gizmo to the flower clone
designGizmoManager.positionGizmoEnabled = true;
designGizmoManager.attachToMesh(theFlowerCopy);
//set the clone as the current flower and show bounding box
theCurrentFlower.obj = theFlowerCopy;
theCurrentFlower.obj.showBoundingBox = true;
//add the flower to the selected flowers map
selectedFlowersMap.set(theFlowerCopy.uniqueId, theFlowerCopy);
set_gizmo_style("#positionGizmo");
$("#gizmoToolsDiv").css('display','flex');
designGizmoManager.positionGizmoEnabled = true;
designGizmoManager.attachToMesh(theFlowerCopy);
}



