xxv / jsc3d

Automatically exported from code.google.com/p/jsc3d
31 stars 20 forks source link

Calculate Surface area of 3D Object #116

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hello, Firstly i would like to thank you for  your excelent 3D software.

I am trying to find out the surface Area of a loaded 3D object but could not
find any method that would return the surface area.

Is there a way to calculate the surface area based on the vertex buffers?

I am using the latest version.

Thank you for your help!

Alberto

Original issue reported on code.google.com by andrad...@gmail.com on 24 Sep 2014 at 2:55

GoogleCodeExporter commented 9 years ago
That's quit easy.  The total area of a mesh's outer surface is the sum of the 
area of all the triangles. If a facet have more than 3 vertices, we just break 
it up following the triangle fan splitting princeple.  The area of each 
triangle can be computed using the cross product of the edge vectors.

I used to write an unoptimized implementation of this for someone. Just add the 
following function to your code:

  function calculateOuterSufaceArea(mesh) {
    var area = 0;
    var ibuf = mesh.indexBuffer;
    var vbuf = mesh.vertexBuffer;
    // walk through all faces, summing up the surface area
    var i=0, j=0;
    while (i < mesh.faceCount) {
      var v0, v1, v2;
      var x0, y0, z0, x1, y1, z1, x2, y2, z2;
      var dx1, dy1, dz1, dx2, dy2, dz2;
      var cpx, cpy, cpz;
      v0 = ibuf[j++] * 3;
      v1 = ibuf[j++] * 3;
      // calculate the area of this face
      do {
        v2 = ibuf[j++] * 3;
        x0 = vbuf[v0    ];
        y0 = vbuf[v0 + 1];
        z0 = vbuf[v0 + 2];
        x1 = vbuf[v1    ];
        y1 = vbuf[v1 + 1]; 
        z1 = vbuf[v1 + 2];
        x2 = vbuf[v2    ];
        y2 = vbuf[v2 + 1];
        z2 = vbuf[v2 + 2];
        dx1 = x1 - x0;
        dy1 = y1 - y0;
        dz1 = z1 - z0;
        dx2 = x2 - x0;
        dy2 = y2 - y0;
        dz2 = z2 - z0;
        cpx = dy1 * dz2 - dz1 * dy2;
        cpy = dz1 * dx2 - dx1 * dz2;
        cpz = dx1 * dy2 - dy1 * dx2;
        area += Math.sqrt(cpx*cpx + cpy*cpy + cpz*cpz);
        v1 = v2;
      } while (ibuf[j] >= 0);
      // continue to next face
      j++;
      i++;
    }
    return 0.5 * area;
  }

The function can be used like this:

  // output the surface area of the first mesh after a model is loaded completely
  var mesh = viewer.getScene().getChildren()[0];
  console.info('surface area = ' + calculateOuterSufaceArea(mesh));

In most cases, your model may consist of more than one mesh. To calculate the 
total surface area:

  // compute and output the total surface area of a whole model after it has been loaded completely
  var totalArea = 0;
  viewer.getScene().forEachChild( function(mesh) {
    totalArea += calculateOuterSufaceArea(mesh);
  };
  console.info('total area = ' + totalArea);

That's it.

Original comment by Humu2...@gmail.com on 24 Sep 2014 at 4:13

GoogleCodeExporter commented 9 years ago
Thank you, Thank you, Thank you  my friend. 
SAVED MY LIFE.
The world would be a better place if we had more people like you.

Best regards,

Alberto.

Original comment by andrad...@gmail.com on 24 Sep 2014 at 8:04