如何在Three.js中计算STL的墙体体积

时间:2018-11-16 18:57:19

标签: javascript three.js 3d stl volume-rendering

我面临很大的挑战,我正在开发一个软件来计算3d印象的成本。为此,我需要获取STL的体积以计算重量。用克,我可以轻松计算价格。 问题是我想获取墙壁的体积和填充物的体积,墙壁大约有1mm,填充物的其余体积。墙壁是实心的,填充物有一定百分比的填充物(例如30%)。有一些数字可以填充更多的墙,反之亦然。 两者的数量都是在Three.js中计算的。现在这就是我正在尝试的。我计算了零件的总体积,并将零件的体积缩放到没有墙的较低比例(将x,y和z的比例缩小为1mm),然后将两者相减。

//x, y and z are the size of mesh
//scale is the percentaje of scaling(uniform on all axes)
function calculateVolume(mesh,scale,x,y,z){
    //Scale the mesh
    x= x*scale;
    y= y*scale;
    z= z*scale;
    var volume = 0;
    var volume_wall = 0;
    var volume_infill = 0;
    var volume_reduced = 0;
    //Calculate the proportion to be reduced with walls of 1mm of each side
    var proportion_x = (x-10)/x;
    var proportion_y = (y-10)/y;
    var proportion_z = (z-10)/z;

    //I travel array of mesh triangles
    mesh.traverse(function (child){
    if (child instance of THREE.Mesh){
        //I get array of vector positions
        var positions = child.geometry.getAttribute("position").array;
        for(var i=0;i<positions.length; i+=9){
            //I calculate volume total of triangle
            volume += volumeOfVectors(positions,i,scale,scale,scale);
            //I calculate volume of triangle minus the walls
            volume_reduced += volumeOfVectors(positions,i,scale*proportion_x,
                scale*proportion_y,scale*proportion_z);

            }
        }
    });
    //I convert volume in mm^3 to cm^3 
    volume = volume / 1000;
    volume_reduced = volume_reduced / 1000;

    //I calculate the wall volume
    volume_wall = volume - volume_reduced;
    //I set the fill volume as 30%
    volume_infill = volume_reduced *0.30;
    // 1.24 is the density
    console.log("Volume 100% infill:"+volume*1.24); 
    console.log("Volume whitout wall:"+volume_reduced*1.24);        
    console.log("Volume wall:"+volume_wall*1.24);   
    console.log("Volume infill:"+volume_infill*1.24);

    return [volume_wall,volume_infill];
}

//Calculating volume with the vectors of the triangle
function volumeOfVectors(positions,i,scale_x,scale_y,scale_z){
    //Point 1
    var t1 = {};
    t1.x = positions[i+0]*scale_x;
    t1.y = positions[i+1]*scale_y;
    t1.z = positions[i+2]*scale_z;
    //Point 2
    var t2 = {};
    t2.x = positions[i+3]*scale_x;
    t2.y = positions[i+4]*scale_y;
    t2.z = positions[i+5]*scale_z;
    //Point 3
    var t3 = {};
    t3.x = positions[i+6]*scale_x;
    t3.y = positions[i+7]*scale_y;
    t3.z = positions[i+8]*scale_z;
    //Volumen calcule
    return  signedVolumeOfTriangle(t1,t2,t3);   
}


function signedVolumeOfTriangle(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;
}

但是这种方法不准确。由于对象在各个方向上都按比例缩放,因此将体积作为第一张图像。 3D红色物体已缩放比例以移除墙壁,而透明物体是原始3D对象。如您所见,3d对象无法适应边框。

image problem 1 image problem 2

该音量应为下一张图像。这样,在各个方向上都可以保持1mm的墙。 image good 1 image good 2

您能想到一个想法或前进的方向吗?

0 个答案:

没有答案