I recently submitted a question on Volume Calculation, received some great assistance at this thread and since have developed a function that calculates the volume of a closed mesh in Three JS. The variable face4 is a true/false that divides the face into two triangles, for Face3 meshes. My geometry is mostly custom Face4 construction.
function volumeCalc(object, face4){
if (face4 == false) {
for (var i=0; i<object.geometry.faces.length; i++) {
var pA = (object.geometry.faces[i].a);
var qA = (object.geometry.faces[i].b);
var rA = (object.geometry.faces[i].c);
var Px = object.geometry.vertices[pA].x;
var Py = object.geometry.vertices[pA].y;
var Pz = object.geometry.vertices[pA].z;
Pxlist.push(Px);
Pylist.push(Py);
Pzlist.push(Pz);
var Qx = object.geometry.vertices[qA].x;
var Qy = object.geometry.vertices[qA].y;
var Qz = object.geometry.vertices[qA].z;
Qxlist.push(Qx);
Qylist.push(Qy);
Qzlist.push(Qz);
var Rx = object.geometry.vertices[rA].x;
var Ry = object.geometry.vertices[rA].y;
var Rz = object.geometry.vertices[rA].z;
Rxlist.push(Rx);
Rxlist.push(Ry);
Rzlist.push(Rz);
}
} else {
for (var i=0; i<object.geometry.faces.length; i++) {
var pA = (object.geometry.faces[i].b);
var qA = (object.geometry.faces[i].c);
var rA = (object.geometry.faces[i].d);
var Px = object.geometry.vertices[pA].x;
var Py = object.geometry.vertices[pA].y;
var Pz = object.geometry.vertices[pA].z;
Pxlist.push(Px);
Pylist.push(Py);
Pzlist.push(Pz);
var Qx = object.geometry.vertices[qA].x;
var Qy = object.geometry.vertices[qA].y;
var Qz = object.geometry.vertices[qA].z;
Qxlist.push(Qx);
Qylist.push(Qy);
Qzlist.push(Qz);
var Rx = object.geometry.vertices[rA].x;
var Ry = object.geometry.vertices[rA].y;
var Rz = object.geometry.vertices[rA].z;
Rxlist.push(Rx);
Rxlist.push(Ry);
Rzlist.push(Rz);
}
}
for (i=0;i < Pxlist.length; i++){
pv = Pxlist[i]*Qylist[i]*Rzlist[i]; + Pylist[i]*Qzlist[i]*Rxlist[i]; + Pzlist[i]*Qxlist[i]*Rylist[i]; - Pxlist[i]*Qzlist[i]*Rylist[i]; - Pylist[i]*Qxlist[i]*Rzlist[i]; -Pzlist[i]*Qylist[i]*Rxlist[i];
pvlist.push(pv);
}
// calculate the total of these, I'm using _.js to add all values in the list.
addUp = (_.reduce(pvlist, function(memo, num){ return memo + num; }, 0))/6;
This is based on the formula
pv = Px*Qy*Rz + Py*Qz*Rx + Pz*Qx*Ry - Px*Qz*Ry - Py*Qx*Rz - Pz*Qy*Rx;
I execute the following on the THREE.Geometry before creating a mesh :
geom.mergeVertices();
geom.computeCentroids();
geom.computeFaceNormals();
geom.computeVertexNormals();
var modifier = new THREE.SubdivisionModifier( x );
modifier.modify( geom );
The volume calculation is correct in all cases of subdivision where x > 0 . When x = 0 or there is no Subdivision, it is incorrect, by orders of magnitude.
Any ideas? Also would appreciate advice on how to clean up the function for use by others, this is my first attempt at open-source contribution. Thank you.