Import gITF and Export STL doesn´t represent the scene

Dear community,

I’m having trouble exporting a scene as an STL and I’m really hoping for your support after lots of trial and error.

Export STL doesn’t represent the scene correctly

The glTF file is stored in Dropbox: TestGLB.glb

Tested with three.js editor

It doesn’t work with the implementation either:

const glbfoader = new GLTFLoader();
glbfoader.load('TestGLB.glb', function(glb){
	scene.add(glb.scene);
})
//one of many solutions that unfortunately didn't work ^^ from https://github.com/mrdoob/three.js/issues/18572
function createMeshesFromInstancedMesh ( instancedMesh ) {
	var group = new THREE.Group();

	var count = instancedMesh.count;
	var geometry = instancedMesh.geometry;
	console.log(instancedMesh)

	for ( var i = 0; i < count; i ++ ) {
		console.log("Instance: ", i , " von ", count)
		var material = instancedMesh.material.clone();
		instancedMesh.getColorAt( i, material.color );

		var mesh = new THREE.Mesh( geometry, material );

		instancedMesh.getMatrixAt( i, mesh.matrix );
		mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );

		group.add( mesh );

	}

	group.copy( instancedMesh );
	group.updateMatrixWorld(); // ensure correct world matrices of meshes

	return group;

};
//https://threejs.org/docs/#examples/en/exporters/STLExporter
function exportBinary() {
	console.log("test test")
	const sceneExport = createMeshesFromInstancedMesh(scene)
	//const result = exporter.parse( scene, { binary: true } );
	const result = exporter.parse( sceneExport, { binary: true } );
	saveArrayBuffer( result, 'box.stl' );

}

What ideas do you have for creating an STL export from TestGLB.glb file?

Thank you very much for all suggestions!

Best wishes :blush:
Kikki

Ok so I loaded and exported your GLTF the simplest way I could…

Here the GLB is loaded:

When I export it to STL, i get this (after loading in blender)

I dug into your file and see its using lots of instancedMeshes which have to be handled differently.

After a short burst of heroic effort, I managed to produce this:

I put this in a “glitch” that loads your glb and saves it to user downloads… hopefully you can adapt this to your needs:

https://coconut-achieved-grandparent.glitch.me

And here’s the code by itself:


let convertGLBToSTL = (url,ondone) => {
  function downloadSTL(scene, fileName = "model.stl") {
    const exporter = new STLExporter();
    const stlString = exporter.parse(scene);
    const blob = new Blob([stlString], { type: "model/stl" });
    const link = document.createElement("a");
    link.style.display = "none";
    document.body.appendChild(link);
    link.href = URL.createObjectURL(blob);
    link.download = fileName;
    link.click();
    document.body.removeChild(link);
  }

  new GLTFLoader().load(
    url,
    (glb) => {
     
      //Optional: Add the GLB to our main scene for visualization
      scene.add(glb.scene);
      
      let meshes = [];
      glb.scene.traverse((e) => e.isMesh && meshes.push(e));

      let outscene = new THREE.Scene();

      let addMesh = (geometry, matrix) => {
        let g = geometry.clone();
        g.applyMatrix4(matrix);
        outscene.add(new THREE.Mesh(g));
      };

      meshes.forEach((m) => {
        if (m.isInstancedMesh) {
          let mat = new THREE.Matrix4();
          for (let i = 0; i < m.count; i++) {
            m.getMatrixAt(i, mat);
            addMesh(m.geometry, mat);
          }
        } else {
          addMesh(m.geometry, m.matrixWorld);
        }
      });
      ondone && ondone(outscene);
      downloadSTL(outscene);
    }
  );
};
3 Likes

thank you very much for your effort, this helps me a lot :+1: :+1:

1 Like