Removing objects from scene not working

I’m loading a Blender generated gltf using GLTFLoader and then I want to remove a bunch of meshes from it to reduce the file size and export it using the GLTFExporter and USDZExporter so that the file can then be sent to a server to be saved.

Removing the objects is failing and I’m not sure why. Here is a short version of the code:

const loader = new GLTFLoader();
loader.load( myModel, async function ( gltf ) {
		gltf.scene.traverse( function( node ) {	
			if (node instanceof THREE.Mesh) {
				node.geometry.dispose();
				gltf.scene.remove(node);
			}
		});
		console.log("---------");
		gltf.scene.traverse( function( node ) {	
			if(node instanceof THREE.Mesh){
				console.log(node);
			}	
		});
} );

This should remove all the objects from the gltf.scene and in the second traverse there should therefore be no output.

However, ALL the objects are still there and console.log out. I don’t want to dispose of the material by the way because that’s shared between meshes.

I’m on a very tight deadline so any support is welcome.

Thank you.

hi @Doug_Lapsley
it appears that you are trying to remove objects from the callback attribute gltf with gltf.scene.remove(node);
I never seen a procedure like this, gltf.scene is not your real scene but only a callback attribute part.
there is a possibility that you cannot use scene.remove(node) on the json object that composes the attribute… but I’m not sure :woozy_face:
I try to answer since it seems to be urgent for you
anyway i hope it will be useful
Usually, in order to remove something from a scene, objects must be added before to the same scene.
Where do you add objects to your current scene?
You say “ALL the objects are still there” but do you see your objects added to your threejs scene or have you only a number of console.log(your traversed node) from your second traverse?

Could you provide an onlin working sample?

Thanks for getting back to me. I just had a deeper look based on your comments here and it seems that you have to remove the item from the parent object and not the scene. You can do this on the callback response object. You can’t remove within the iteration though or it kicks and error (presumably because it’s removing objects in the same tree that it’s iterating). Here is a sample that worked for me:

		let objectsToRemove = [];
		gltf.scene.traverse( function( node ) {	
			if (node instanceof THREE.Mesh) {
				if(!node.visible){
					objectsToRemove.push(node);
				}
			}
		});
		objectsToRemove.forEach(node => {
			let parent = node.parent;
			parent.remove( node );
		});
		console.log("---------");
		gltf.scene.traverse( function( node ) {	
			if(node instanceof THREE.Mesh){
				console.log(node);
			}	
		});

Prior to calling this I hide all objects and then unhide the ones that I want to keep so that I can do the if(!node.visible){ conditional to select the objects that are no longer needed.

Thanks again for your swift reply!