简体   繁体   中英

How do I export geometry from a Three.js scene as an OBJ that has been modified?

Every time I export and save the model (SkinnedMesh) from my Three.js scene the original imported model is saved. This happens even though I modify the model by rotating a bone and changing the value of a morph target.

I've checked for changes to the geometry's data in the console window and it shows that the bone and morph target information has been updated. But for some reason when I export and save, the updated model is not saved.

Here is my render() function where the model is exported and saved as an OBJ.

function render() {

    cube.rotation.x += guiControls.rotationX;
    cube.rotation.y += guiControls.rotationY;
    cube.rotation.z += guiControls.rotationZ;

    spotLight.position.x = guiControls.lightX;
    spotLight.position.y = guiControls.lightY;
    spotLight.position.z = guiControls.lightZ;

    camera.lookAt(lookAtPos);

        scene.traverse(function(child){
        if (child instanceof THREE.SkinnedMesh){  

            child.skeleton.bones[13].rotation.y = guiControls.Shoulder;
            child.scale.x = guiControls.ScaleX;
            child.scale.y = guiControls.ScaleY;
            child.scale.z = guiControls.ScaleZ;
            child.position.x = guiControls.PositionX;
            child.position.y = guiControls.PositionY;
            child.position.z = guiControls.PositionZ;

            child.geometry.dynamic = true;
            child.geometry.verticesNeedUpdate = true;
            child.geometry.elementsNeedUpdate = true;
            child.updateProjectionMatrix = true;

            if(save){
              var exporter = new THREE.OBJExporter();
              var result = exporter.parse(child);

              var saveData = (function () {
                var a = document.createElement("a");
                document.body.appendChild(a);
                a.style = "display: none";
                return function (data, fileName) {
                      var obj = data,
                      blob = new Blob([obj], {type: "octet/stream"}),
                      url = window.URL.createObjectURL(blob);
                  a.href = url;
                  a.download = fileName;
                  a.click();
                  window.URL.revokeObjectURL(url);
                };
              }());

              saveData(result, "ModelOBJExport.obj");

              save = false;
            }

        }
        else if  (child instanceof THREE.SkeletonHelper){
            child.update();
        }
    });

} 

Here is a JSFiddle containing all of my code - https://jsfiddle.net/markskelton/ord9gL1a/ . I was unsure of how to upload my model so that people could use that with my code.

I do not know if some of this is redundant in your case But this is in my save process. After setting the size, position and rotation, try:

    child.updateMatrix();
    child.geometry.applyMatrix(child.matrix);
    child.matrixAutoUpdate = true;
    //reset the matrix to identity if you want to be double sure the matrix is now actually ready for export.
    child.matrix.identity();

For some reason this isn't working for people. I am adding the function I run in its entirety, comments and all. I cannot say why other people cannot get this to work. This works fine for me. I would suggest if people are having issues, to show the code and example problem in a new question.

objSaver.prototype.modifyMeshToRhinoObj = function (mesh) {
        var exporter = new THREE.OBJExporter();
        //we do no save the original extrusion geometry. We clone it, match it's axis and scale to external settings, usually found in Rhino (non adjusted obj up), and save the clone.
        //This is so on re-import it is treated as if it came from any mesh tool.
        var polygonGeometry = new THREE.Geometry().fromBufferGeometry(mesh.geometry._bufferGeometry);
        var volumeClone = new THREE.Mesh(polygonGeometry, [
                new THREE.MeshBasicMaterial({ color: 16711680 }),
                new THREE.MeshBasicMaterial({ color: 16711680 })
        ]);
        volumeClone.scale.set(1, 1, mesh.scale.z);
        volumeClone.rotation.x = de2ra(180);
        volumeClone.rotation.z = de2ra(-90);
        volumeClone.updateMatrix();
        volumeClone.geometry.applyMatrix(volumeClone.matrix);
        volumeClone.matrixAutoUpdate = true;
        volumeClone.matrix.identity();
        volumeClone.geometry.verticesNeedUpdate = true;
        mesh.userData.cloned = true;
        mesh.userData.baseline = mesh.userData.buildingHeight;
        return exporter.parse(volumeClone);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM