Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

figuring out the volume and surface area

Discussion in 'Editor & General Support' started by hiromi, Dec 30, 2011.

  1. hiromi

    hiromi

    Joined:
    Dec 29, 2011
    Posts:
    2
    Hello, all.
    How can I figure out the volume and surface area of objects.
    The objects are atypical.
    Please help me out.
     
  2. Rochel

    Rochel

    Joined:
    Dec 26, 2011
    Posts:
    12
    For the area i guess one easy way is to calculating the area of each polygon(easy math as it should be all triangles) and adding it together. But still some serious script work are involved. A little more info would be nice.
     
  3. BigArt

    BigArt

    Joined:
    Jun 5, 2009
    Posts:
    6
    Hi Hiromi, not sure if you mean from within Unity, but if you can export your mesh into Blender it has some scripts you might find useful:

    Python Script for Calculating the Volume of Objects
    http://www.blendernation.com/2007/05/11/python-script-calculating-the-volume-of-objects

    Some Architectural Measuring Tools:
    http://wiki.blender.org/index.php/Community:Science/Architecture

    Maybe these scripts can be reworked to integrate with Unity? Not my field of expertise though, but I hope this is of value.

    /Art
     
  4. tchpowdog

    tchpowdog

    Joined:
    Nov 25, 2011
    Posts:
    255
    I would do what BigArt said to find the base volume... In Unity, if the object gets scaled or whatever, you can then just scale the volume you've precaculated... Unless you're wanting to do something totally different and my comment is redundant...

    Btw, thanks BigArt, I will definitely use the Measuring tool in Blender... I'm a CAD operator/engineer by trade, so this tool will definitely help me create models easier in Blender
     
  5. hiromi

    hiromi

    Joined:
    Dec 29, 2011
    Posts:
    2
    BigArt,
    Where is the Python scripts? Sorry. I searched the link you wrote, but I can't find it.
    Please tell me the detail about the volumn calculating.
    I need the volumn calculating within Unity. I'm unfamiliar with running Python scripts, but Python scripts also will be helpful to me. Maybe I can rework it with Unity.
     
    Last edited: Jan 2, 2012
  6. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    Area of polygon(mesh doesnt matter)
    mVertices is the Vertex array(vector3 for vertex positions) that makes up the polygon
    Code (csharp):
    1.     public float Area () {
    2.         Vector3 result = Vector3.zero;
    3.         for(int p = mVertices.Length-1, q = 0; q < mVertices.Length; p = q++) {
    4.             result += Vector3.Cross(mVertices[q], mVertices[p]);
    5.         }
    6.         result *= 0.5f;
    7.         return result.magnitude;
    8.     }
    For volume, just use bounding box of the mesh.
     
    atomicjoe and (deleted member) like this.
  7. kOrc

    kOrc

    Joined:
    Sep 15, 2012
    Posts:
    7
    This is a very elegant solution (bringing out cross-product for area of triangle) and I like it a lot. Thanks! However, this exact code changes area based on orientation of the mesh in world space, or if parts of the mesh are oriented opposite to other parts, because you add up the cross products as vectors before turning into a magnitude. So you should really use:

    Code (csharp):
    1.     public float Area () {
    2.         float result = 0;
    3.         for(int p = mVertices.Length-1, q = 0; q < mVertices.Length; p = q++) {
    4.             result += (Vector3.Cross(mVertices[q], mVertices[p])).magnitude;
    5.         }
    6.         return result*0.5f;
    7.     }
    While the original is less CPU-intensive (more efficient, in a sense?), it is often incorrect, which is a much bigger deal ;)
     
    atomicjoe likes this.
  8. il_fantasticatore

    il_fantasticatore

    Joined:
    Jan 16, 2018
    Posts:
    1
    I found another more generic solution using mesh triangles.
    Theory says that: if a triangle is specified by vectors u and v originating at one vertex, then the area is given by half of the corresponding parallelogram, i.e., area = 1/2|u x v|, where |u x v| is the magnitude of a two-dimensional cross product (source: http://mathworld.wolfram.com/TriangleArea.html)
    Given that, you have to calculate two vectors by the difference between two triangle's vertices and than cross product them, considering that the two vectors must be originating from the same vertex, as theory says.
    Eventually, the area of a generic whatever oriented polygon, or the total surface of a generic object, will be the sum of the areas of it's triangles. Here's the algorithm:
    Code (CSharp):
    1. Vector3[] vertices = this.GetComponent<MeshFilter>().mesh.vertices;
    2. int[] triangles = this.GetComponent<MeshFilter>().mesh.triangles;
    3.  
    4. float result = 0f;
    5. for(int p = 0; p < triangles.Length; p += 3)
    6. {
    7.      result += (Vector3.Cross(vertices[triangles[p+1]] - vertices[triangles[p]],
    8.                  vertices[triangles[p+2]] - vertices[triangles[p]])).magnitude;
    9. }
    10. result *= 0.5f;
    The only possible issue with my solution is the scale factor. In Unity, mesh vertices are store without any information about scale, so if your GameObject is scaled along any axes, you should modify the algorithm applying the transformation to each vertex.
     
    Last edited: Feb 21, 2018
  9. AntonQvarfordt

    AntonQvarfordt

    Joined:
    Mar 14, 2013
    Posts:
    27
  10. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    264
    hi guys, i have used this function but the problem is its not returning the correct area because i have calulcated the same object in revit. Revit calculation of area is different.
    Code (CSharp):
    1.   public float Area(Mesh m)
    2.     {
    3.  
    4.         Vector3[] mVertices = m.vertices;// m.bounds;
    5.         Vector3 result = Vector3.zero;
    6.         for (int p = mVertices.Length - 1, q = 0; q < mVertices.Length; p = q++)
    7.         {
    8.             result += Vector3.Cross(mVertices[q], mVertices[p]);
    9.         }
    10.         Debug.Log(result);
    11.         result *= 0.5f;
    12.         return result.magnitude;
    13.  
    14.     }
     
  11. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    243
    Old post I know but I came across this as I'm looking into the same.
    At the end, you are first returning the debug, and then doing additional calculations and returning that.. So the result in the console from Debug will be wrong anyways.

    EDIT:
    Nevermind, I also get strange results from the whole script.
    Have you found a solution?
     
    Last edited: Nov 18, 2020