Copy a scene or object for use in another project

I’m trying to copy used meshes for use in another project, but I can’t copy a multidimensional object. here is the original mesh object


this is obtained after the method .toJSON()
bandicam 2024-01-09 13-53-40-765
and this happens when = JSON.stringify(obj);
bandicam 2024-01-09 14-00-21-956
I can’t seem to completely copy the entire multidimensional object, how can this be done?

1 Like

GLTFExporter might be what you’re looking for
:eyes:

no, no no. I need to move objects from one HTML to another HTML. For example, I created a scene in three.js editor and I want to move all 3D objects into my HTML project, with the ability to edit them.

Well, in that case, GLTFExporter might be what you’re looking for (and GLTFLoader on the other side) :eyes:

2 Likes

no, that’s not true.


I need a format that I can export and edit each object in the scene separately; in the case of gltf, I will not be able to edit the settings of each scene object separately, only all objects of 1 gltf file at the same time. correct me if this is not true

GLTFExporter exports to GLTF, which is a JSON, which is in fact a text format :smiling_face_with_tear:?


Edit: The screenshot you’ve shared is GLB, not GLTF.

in fact, I’m just looking for an opportunity to somehow translate a multidimensional mesh object (as in the picture)


so that during translation I retain all the parameters of the original object, and not 10%, if this is not possible, and in such cases you need to use GLTFExporter, and there are no other options, then write it that way.

Using ObjectLoader on the resulting object.toJson will yield the same object once loaded, the generator stores a simplified way of reconstructing the object once loaded again, if you’re wondering about your custom properties afaik you can store it all in the default userData object which should then carry through once loaded again…

write using the code how you would do it

The threejs editor has an “publish” button that sends you a runnable zip.

you are kind of struggling against a paradigm. in the imperative world there is no editor-code hand-off and all solutions are basically export/import hacks, you turn your scene into a sealed blob/blackbox and then load that. if you want to make changes later on you either fish out nodes by querying, which creates a fork between the design model and the runtime model, or the whole editor-to-code process starts again.

this is an archaic way to go about it, and it has been practically solved around 2010 with the onset of declarativity. the whole wide web is declarative, and three can be as well. then you have tools like this:

now your code is the source of truth. you change something in the editor and it gets fed back into your source code. you change something in your code and it gets reflected in the editor. the design process and the actual code are one and the same.

declarativity also solves gltf, which in the imperative world is a blob, a singleton. in the declarative world you have the scene under your control.

my project has nothing to do with https://threejs.org/editor/. At the moment it looks like this


but all this does not matter, since now I have a choice between 2 options for saving the project.
Option 1 - (boring) I create an array for all created meshes, in which I place the data of all my manipulations with the mesh, which I can upload as json, after which I also write a script for loading the project and creating all the meshes, in accordance with json file.
Option 2 - (which I asked about in this thread) Maybe there is a simpler option, something like taking information about all my meshes when saving

for(var i=1; i<mesharray.length;i++){
jsonmesharray.push(mesharray[i].toJSON())
}

and when loading the project

for(var i=1; i<jsonmesharray.length;i++){
mesharray[i]= new THREE.Mesh(jsonmesharray[i])
}

Well, you must admit that it is much simpler


but it won’t work

mesharray[i]= new THREE.Mesh(jsonmesharray[i])

What you have above won’t work…

mesharray[i]= new THREE.Mesh(jsonmesharray[i])

You’ll need to load the JSON objects through ObjectLoader

jsonLoader = new THREE.ObjectLoader()
jsonLoader.load('path/to/jsonmesharray[i].json', function(jsonModel) {

  scene.add(jsonModel)
}

Or Parse the toJson objects

jsonLoader = new THREE.ObjectLoader()
jsonLoader.parse(jsonmesharray[i], function(jsonModel) {

  scene.add(jsonModel)
}
1 Like

You cannot serialize functions or classes which can then be deserialized back into the same structure.

This is a Javascript thing and has nothing to do with your project, threejs or whatever library or framework you are using.

This is why using something like GLTFExporter is suggested to begin with. You store your scene as a GLTF file, which you can import in another project using GLTFLoader. The result of this will be your editable multidimensional object that you’ve been asking for.

1 Like

If I use GLTF, then I will not be able to control its child elements, just, for example, change the scale of the entire GLTF.

your method is the most successful if we talk about one mesh.

The only drawback is that I lose color, maybe I screwed up somewhere, since the color in JSON is preserved

I’m still figuring out how to pass an array or object with all the meshes. is it possible to use input type=“file” ?

<input type="file" onchange="readFile(this)">

For complex geometries and certain parts of them, I do this with readFile and text files with a self-defined structure. The export is quite easy to accomplish, as is the import of the data itself. However, the processing of the imported data is then quite complex for me!

A partial example

    const f = fileLoad.files[ 0 ];
    
    if ( f.type.match( /text.*/ ) ) {
        
        reader.readAsText( f );
         
        reader.onload =  e => { 
            
            // separate by , values into array
            coords[ apdIdx ][ cutIdx ] = e.target.result.match( /-?\d+(\.\d+)?/g ).map( Number ); 

            processLoadedGeo ( );  // very complex
            
        }
        
    }

GLTF preserves hierarchy of objects, so if you do not merged them in one monolith object, you should be able to access individual elements and control them after you read the GLTF (or GLB) file.

Edit:
Here is a demo of a GLB model which elements are moved individually:

https://codepen.io/boytchev/full/vYPyrPy

image

@PavelBoytchev This method is not suitable in this case, since when creating the mesh it is placed in an array

mesharray[nowcontrol.value-0]= new THREE.Mesh(geosettings,matsettings)

the parameter nowcontrol.value is the controller inside my project
bandicam-2024-01-13-19-51-40-957
where did -0 come from? The thing is that nowcontrol.value is a string, and -0 converts the string into a number, here I use кастыль (not a very beautiful, but quite effective way). But all this is not important, because even if I download the GLTF model.

glftload.load('res/save.glb',(gltfScene)=>{
mesharray[nowcontrol.value-0] = gltfScene.scene
scene.add(mesharray[nowcontrol.value-0]);
})

it will still be in my array under a certain number, and I will only be able to control everything together, but not separately. Yes, most likely this is my bad decision, and it’s not worth doing, but in the current situation, the best way would be to use Jason files. This will also come in handy when I get to the stage of creating an HTML file using node

  var fs = require('fs');
fs.writeFileSync('index.html',data)

I was just pointing out, that the problem is not a problem of GLTF per se. Even if the meshes are in one GLTF, you can read the model, get the meshes in it and put them in your array as separate meshes.

However, I think that you should just use the technique that best fits your needs.