【问题标题】:How do I export geometry from a Three.js scene as an OBJ that has been modified?如何将 Three.js 场景中的几何图形导出为已修改的 OBJ?
【发布时间】:2016-12-12 23:53:10
【问题描述】:

每次我从我的 Three.js 场景中导出并保存模型 (SkinnedMesh) 时,都会保存原始导入的模型。即使我通过旋转骨骼和更改变形目标的值来修改模型,也会发生这种情况。

我在控制台窗口中检查了几何数据的变化,它显示骨骼和变形目标信息已更新。但是由于某种原因,当我导出并保存时,更新的模型没有保存。

这是我的 render() 函数,模型导出并保存为 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();
        }
    });

} 

这是一个包含我所有代码的 JSFiddle - https://jsfiddle.net/markskelton/ord9gL1a/。我不确定如何上传我的模型,以便人们可以在我的代码中使用它。

【问题讨论】:

    标签: javascript three.js geometry export


    【解决方案1】:

    我不知道在你的情况下这是否是多余的但这是在我的保存过程中。设置好大小、位置和旋转后,试试:

        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();
    

    由于某种原因,这对人们不起作用。我正在添加我完整运行的函数、cmets 和所有函数。我不能说为什么其他人不能让它发挥作用。这对我来说很好。如果人们遇到问题,我会建议在新问题中显示代码和示例问题。

    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);
    };
    

    【讨论】:

    • 您好,感谢您的回复!似乎仍在导出原始模型。您的答案是否适用于 Three.js 的最新版本?
    • 我还对我从场景中导出和保存的两个 OBJ 文件进行了差异比较,一个模型位于原始位置,另一个改变了变形目标。两个 OBJ 文件完全相同。
    • 我已经用我自己的项目、cmets 和所有类中的实际方法修改了我的答案,这对我有用,以防万一有什么东西使它起作用。我不能说为什么其他人不能让它发挥作用。这对我来说很好。如果人们遇到问题,我建议在堆栈上的新问题中显示代码和示例问题。
    猜你喜欢
    • 1970-01-01
    • 2020-08-20
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2018-01-28
    相关资源
    最近更新 更多