How to perform a deep clone of a scene?

I have a Scene that I want to copy and then change it without effecting the original Scene.

Object3D copy method is copying by reference.

How can I duplicate to an independent Scene?

Try clone().

Tried it but still the material etc. are referenced to the original object.

After you clone the scene, traverse it and clone referenced properties like

myScene.traverse(function(object) {

        if ( object.isMesh ) {

            object.material = object.material.clone();

        }

    });

You need to do it as deep as you require, a cloned material will still share it’s program for example, in case you don’t want this to be referenced either.

@Fyrestar works :muscle:t4:

Thank you!

Here is some code that uses this example clone - I load one .obj, and make a pile of copies of it - setting the position and color of each one

Blockquote

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(‘textures/cont1/’);
mtlLoader.load(‘container2.mtl’, function (materials) {
materials.preload();

  //var material = new THREE.MeshFaceMaterial(materials);
  materials.transparency = 0.2;
  materials.transparent = true;
  materials.opacity = 0.6;
  //material.depthWrite = false;
  //
  var objLoader = new THREE.OBJLoader();
  objLoader.setMaterials(materials);
  objLoader.setPath('textures/cont1/');

  objLoader.load('/Container2.obj', function (container) {
  	for (var sc = 0; sc < posns.length; sc++) {
  		var scale = posns[sc].scale;
  		var rotation = posns[sc].rotation;
  		var posn = posns[sc].position;
  		var model3d = new THREE.Object3D();
  		//clone main obj
  		model3d = container.clone();
  		//clone obnj meshes
  		model3d.traverse(function (object) {
  			if (object.isMesh) {
  				object.material = object.material.clone();
  			}
  		});

  		model3d.scale.x = parseFloat(scale.x);
  		model3d.scale.y = parseFloat(scale.y);
  		model3d.scale.z = parseFloat(scale.z);

  		//container.position = new THREE.Vector3(posn.x, posn.y, posn.z);
  		model3d.position.x = posn.x;
  		model3d.position.y = posn.y;
  		model3d.position.z = posn.z;

  		model3d.rotation.x = rotation._x;
  		model3d.rotation.y = rotation._y;
  		model3d.rotation.z = rotation._z;

  		var color = '999933';//default grey
  		if (!posns[sc].color) {
  			var rnd = (Math.random() * 100);
  			if (rnd >90) {
  				console.log('blue');
  				posns[sc].color = '456F87';
  			} else if (rnd > 50) {
  				console.log('red');
  				posns[sc].color = 'C04B0C';//
  			}else if (rnd > 20) {
  				console.log('yellow');
  				posns[sc].color = 'F3CD8B';
  			}else {
  				console.log('grey');
  				posns[sc].color = color;

  			}

  		}
  		model3d.traverse(function (child) {
  			if (child instanceof THREE.Mesh) {
  				//var c = hexToRgb(color);
  				var c = hexToRgb(posns[sc].color);
  				child.material.color = new THREE.Color("rgb(" + c.r + ", " + c.g + ", " + c.b + ")");
  				//child.material.emissive.setHex(0xdaa514);
  				//child.material.opacity = 1 + Math.sin(new Date().getTime() * .0025);
  				child.castShadow = true; //default is false
  				child.receiveShadow = false; //default
  			}
  		});
  		if (!model3d.userData.color) {
  			model3d.userData.color = posns[sc].color;
  		};

  		model3d.name = posns[sc].name;

  		group = new THREE.Group();
  		scene.add(group);

  		var textMaterial = new THREE.MeshBasicMaterial({
  			color: new THREE.Color(1, 1, 1),
  			side: THREE.DoubleSide,
  			wireframe: false
  		});

  		var textShapes = font.generateShapes(model3d.name, .4);

  		var geometry = new THREE.ShapeBufferGeometry(textShapes);
  		geometry.computeBoundingBox();

  		var text = new THREE.Mesh(geometry, textMaterial);

  		text.position.x = posn.x - ((geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2);
  		text.position.y = posn.y + 5;
  		text.position.z = posn.z + 0;

  		group.add(text);
  		group.add(model3d);


  		containers.push(model3d);

  		scene.add(model3d);
  	}

  }, onProgress, onError);

});

Blockquote

Hello. you can throw off all the code? I will be very grateful, thanks.

Should the documentation for Object3D.clone() warn that materials will not be cloned ?

-jg-