Can't change material of loaded 3MF file as the object has no normals set - 3MF bug?

I’ve noticed that when loading a 3MF file with the 3MF loader, the resulting group and child meshes do not contain any normal attributes - this seems to work fine if using the baked materials inside the 3MF, but if you try and set a custom material like MeshNormalMaterial, the meshes render as solid black.

reproducable at three.js/webgl_loader_3mf_materials.html at 8f18f8a28ec771d1d4631a665b6db6cc9a203162 · ErinTheSmall/three.js · GitHub

edited from the default example with:

				loader.load( './models/3mf/cube_gears.3mf', function ( object ) {

					object.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) ); 	// z-up conversion

					object.traverse( function ( child ) {
						if (child instanceof THREE.Mesh) {
						    child.material = new THREE.MeshNormalMaterial();
						    child.geometry.computeVertexNormals(true);
						}
						child.castShadow = true;

					} );

					scene.add( object );

				} );

This can sort of be fixed by running .computeVertexNormals() on the mesh, but that produces incorrect normals, and lighting issues

if you remove .computeVertexNormals() but keep the custom material I get this:

and if you remove the “child.material = new THREE.MeshNormalMaterial();” you get the baked textures of the 3mf working fine :

traversing through objects children and setting the material does seem to work for OBJ’s loaded with OBJ loader, as their children meshes do have the normal attribute set when loaded

Looking at the source code for 3MFLoader, it does not support vertex normals. I searched the 3MF file format specification quickly and couldn’t tell whether the format itself includes vertex normals — as a CAD format, it very well may not.

We generally recomend using glTF if you’re able to choose the input format, there are various reasons it tends to be the best choice for web applications.

ah, that’s a shame :frowning: but thank you for confirming this!
sadly in this instance I can’t use another format as I’m working on a 3D printing related tool, and 3MF is the most common modern mesh format for 3D printing

I still have a feeling something odd is going on, but can’t work out exactly what’s causing it:

if I replicate the state of the 3MF meshes by loading an OBJ with the same triangles, and removing the normals attribute then running .computeVertexNormals() on it, I get none of the normal incorrectness shown in image 2 and it renders fine.

something about the data exported by the 3mf loader seems to be causing .computeVertexNormals() to generate incorrect normal data

.computeFaceNormals() also does absolutely nothing to the mesh and it remains black

I wonder if merging vertices before computing vertex normals would help in the examples above?

No visible effect that I can see with MeshNormalMaterial or MeshPhongMaterial applied :frowning:

child.geometry = BufferGeometryUtils.mergeVertices(child.geometry);