计算ThreeJS一个网格的体积大于边界框体积 [英] Calculating the volume of a mesh in ThreeJS is greater than bounding box volume

查看:1261
本文介绍了计算ThreeJS一个网格的体积大于边界框体积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的问题:

边框体积比目计算的体积更小。

Bounding box volume is smaller than volume calculated from mesh.

我已经试过:

首先,我计算边框与以下code卷:

First I calculate the volume of a bounding box with the following code:

//loaded .obj mesh object:
var sizer = new THREE.Box3().setFromObject(obj);
console.log(sizer.size().x*sizer.size().z*sizer.size().y);

日志输出:197112.65382983384

log output: 197112.65382983384

然后,我计算网格的使用量<一href="http://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up">this解决方案与<一个href="http://stackoverflow.com/questions/23279521/three-js-3d-models-calculating-few-volumes-of-object">this解决方案与方法calculateVolume传统几何对象包括如下:

Then I calculate the volume of the mesh using this solution with this solution with the legacy geometry object in the method "calculateVolume" included below:

    console.log(scope.calculateVolume(child));

calculateVolume是类的一部分。我的类方法如下:

calculateVolume is part of a class. My class methods are as follows:

threeDeeAsset.prototype.signedVolumeOfTriangle = function(p1, p2, p3) {
    var v321 = p3.x*p2.y*p1.z;
    var v231 = p2.x*p3.y*p1.z;
    var v312 = p3.x*p1.y*p2.z;
    var v132 = p1.x*p3.y*p2.z;
    var v213 = p2.x*p1.y*p3.z;
    var v123 = p1.x*p2.y*p3.z;
    return (-v321 + v231 + v312 - v132 - v213 + v123)/6;
}

threeDeeAsset.prototype.calculateVolume = function(object){
    var volumes = 0;

    object.legacy_geometry = new THREE.Geometry().fromBufferGeometry(object.geometry);

    for(var i = 0; i < object.legacy_geometry.faces.length; i++){
        var Pi = object.legacy_geometry.faces[i].a;
        var Qi = object.legacy_geometry.faces[i].b;
        var Ri = object.legacy_geometry.faces[i].c;

        var P = new THREE.Vector3(object.legacy_geometry.vertices[Pi].x, object.legacy_geometry.vertices[Pi].y, object.legacy_geometry.vertices[Pi].z);
        var Q = new THREE.Vector3(object.legacy_geometry.vertices[Qi].x, object.legacy_geometry.vertices[Qi].y, object.legacy_geometry.vertices[Qi].z);
        var R = new THREE.Vector3(object.legacy_geometry.vertices[Ri].x, object.legacy_geometry.vertices[Ri].y, object.legacy_geometry.vertices[Ri].z);
        volumes += this.signedVolumeOfTriangle(P, Q, R);
    }

    return Math.abs(volumes);
}

日志输出:336896.1562770668

log output: 336896.1562770668

检查顶点来源:

我也试过buffergeometry,当然,它实际上是一样的数组,但类型化Float32Array和predictably给出了相同的结果:

I also tried buffergeometry and of course, it's really the same array, but a typed Float32Array and predictably gave the same result:

var vol = 0;
scope.mesh.traverse(function (child) {
    if (child instanceof THREE.Mesh) {
        var positions = child.geometry.getAttribute("position").array;
        for(var i=0;i<positions.length; i+=9){

            var t1 = {};
            t1.x = positions[i+0];
            t1.y = positions[i+1];
            t1.z = positions[i+2];

            var t2 = {};
            t2.x = positions[i+3];
            t2.y = positions[i+4];
            t2.z = positions[i+5];

            var t3 = {};
            t3.x = positions[i+6];
            t3.y = positions[i+7];
            t3.z = positions[i+8];
            //console.log(t3);

            vol += scope.signedVolumeOfTriangle(t1,t2,t3);
        }
    }
});
console.log(vol);

日志输出:336896.1562770668

log output: 336896.1562770668

的问题:为什么我的边框成交量较封闭网格的计算量小?

The question: Why is my bounding box volume smaller than the calculated volume of a closed mesh?

也许我缺少的是一个偏移位置这样的事情也许我计算的边界框量错了。我做了谷歌和堆栈,这就是我来找以上signedVolumeOfTriangle功能的几个搜索。这似乎是最常见的公认的方法。

Perhaps I missing something such as an offset position or maybe I am calculating the bounding box volume wrong. I did several searches on google and stack, which is how I came to find the signedVolumeOfTriangle function above. it seems to be the most common accepted approach.

推荐答案

可以与缠绕顺序有问题,你可以尝试从签量,或重新排序参数否定的结果。

Could be a problem with winding order, you could try negating the result from signed volume, or reordering arguments.

的缠绕顺序将是顺时针或逆时针,并且确定多边形的衬面(正常),

The winding order will be clockwise or counterclockwise and determines the facing (normal) of the polygon,

volumes += this.signedVolumeOfTriangle(P, Q, R);

交换 P 研究反转正常,

volumes += this.signedVolumeOfTriangle(R, Q, P);

这可以通过像三角形带存储技术,其中顶点是由相邻三角形共享复杂造成缠绕以备用。

This can be complicated by storage techniques like triangle strips, where vertices are shared by adjacent triangles, causing winding order to alternate.

另一个问题可能是 - 尤其是如果它工作正常进行简单的网格 - 是堕落的顶点。如果你让你的网格从一个编辑器,并网进行了修改和调整了一百万次(通常情况下),它几乎可以保证有退化。

Another problem could be - especially if it works correctly for simple meshes - is degenerate vertices. If you're getting your meshes from an editor, and the mesh has been modified and tweaked a million times (usually the case), it's almost guaranteed to have degenerates.

有可能是一种选择焊接接近顶点的编辑器,可以帮助,或测试与已知良好的网格,例如斯坦福大学的兔子。

There may be an option to weld close vertices in the editor that can help, or test with a known good mesh e.g. the Stanford bunny.

这篇关于计算ThreeJS一个网格的体积大于边界框体积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆