Jump to content
  • Advertisement
Sollum

3D Mesh surface area calculation errors after subdividing

Recommended Posts

Hello!

I have this strange issue with mesh surface area calculation. Surface area increases, if i "subdivide" mesh to be more detailed and add more polygons, even tho the relative size remains the same.
Code is rather simple and the formula itself doesn't matter as much as differentiating results based on polygon count.

float total_area = 0;
int indice_count = finalMeshIndices.length;
for (int i = 0; i < indice_count; i += 3)
{
  float area = 0;

  Vector3 p1 = new Vector3(finalMeshVertexFloatArray[i + 0], finalMeshVertexFloatArray[i + 1], finalMeshVertexFloatArray[i + 2]);
  Vector3 p2 = new Vector3(finalMeshVertexFloatArray[i + 10], finalMeshVertexFloatArray[i + 11], finalMeshVertexFloatArray[i + 12]);
  Vector3 p3 = new Vector3(finalMeshVertexFloatArray[i + 20], finalMeshVertexFloatArray[i + 21], finalMeshVertexFloatArray[i + 22]);

  Vector3 e1 = p2.sub(p1);
  Vector3 e2 = p3.sub(p1);
  Vector3 e3 = e1.crs(e2);

  area = (float) (0.5 * Math.sqrt(e3.x * e3.x + e3.y * e3.y + e3.z * e3.z));

  if (Float.isNaN(area)) System.out.println("NaN... The fuck?");

  total_area += area;
}

I think the issue is with float precision, because i have the same issue if i take a model and flip it.

Here is visual representation
image.png.e7526cf68e7f6b037046b2f9524db25a.png

image.png.eeb1e102509c1c7e29027fa8e7bb194b.png

If i take a cube 1,1,1 its area is ~5
If i upscale it 3 times, its area becomes ~19

So it seems that float precision is a culprit here. At least i guess so.

Edited by Sollum

Share this post


Link to post
Share on other sites
Advertisement

For your sphere this is not surprising. You aren't just dividing the triangles, you are also moving the vertices outwards to lie on the sphere surface (otherwise subdividing wouldn't make the shape any rounder). And when you move those vertices outwards, you are increasing the volume of the shape (and hence the surface area).

Share this post


Link to post
Share on other sites

Sorry for the late reply.

Yes, i though the same, but difference is way way way way way way to big in my opinion.
~5 times bigger surface area from subdividing 2 or 3 times.  And the volume itself becomes ~3 times bigger.

Different example: 
image.png.e2a8f69a2e565f7bcb0448642431d97f.pngimage.png.801b6ab9bf7d53779ddcd69e6efac434.png
 

Same model, only flipped in 3d modeling tool and loaded as a separate model.
Its area and volume differs.

Share this post


Link to post
Share on other sites

Ok, this has to be an issue with how you are calculating the area. Looking at the function in your original post, one thing looks strange to me. The code references an index array, but then it doesn't use the index array to lookup the vertices. Is this an indexed mesh or not?

Share this post


Link to post
Share on other sites
On 7.2.2018 at 8:38 PM, Sollum said:

Vector3 p2 = new Vector3(finalMeshVertexFloatArray[i + 10], finalMeshVertexFloatArray[i + 11], finalMeshVertexFloatArray[i + 12]);

Agree, looks like an indexing bug. Your vertices have 10 floats? Increasing i by 3 makes little sense, probably forgot to read the index?

for (int i = 0; i < indice_count; i += 3)

But why do you allocate the vertices with new? (even if that's intended, you forgot to delete it.) 

:)

Edited by JoeJ

Share this post


Link to post
Share on other sites
2 minutes ago, JoeJ said:

But why do you allocate the vertices with new? (even if that's intended, you forgot to delete it.)

He's programming in Java, not C++ (note the System.out.println near the end).

Share this post


Link to post
Share on other sites

Thanks lads!

Crap, what a lame mistake that was. Fixing it was fast and easy.
 

int i_indiceMod = 10 * i;
Vector3 p1 = new Vector3(finalMeshVertexFloatArray[i_indiceMod + 0], finalMeshVertexFloatArray[i_indiceMod + 1], finalMeshVertexFloatArray[i_indiceMod + 2]);
Vector3 p2 = new Vector3(finalMeshVertexFloatArray[i_indiceMod + 10], finalMeshVertexFloatArray[i_indiceMod + 11], finalMeshVertexFloatArray[i_indiceMod + 12]);
Vector3 p3 = new Vector3(finalMeshVertexFloatArray[i_indiceMod + 20], finalMeshVertexFloatArray[i_indiceMod + 21], finalMeshVertexFloatArray[i_indiceMod + 22]);

 

Everything now seems normal, and both spheres seem to have only marginal difference in surface area. Tho the first one seems to have bigger surface area, but somehow it makes sens to me.
image.png.df5e6cbc8915724c0fd3cfc483749898.pngimage.png.a48574bc84f6842a88ebcf1fa1fdb2dd.png

 

Flipped models are also fixed, but there is small 0.000001 error :D
image.png.3f01332e492048b004336cf5f678474c.pngimage.png.2123132769013595be0d98d520ac32c1.png

For now I am using "new" operator, since calculations are done only once, whilst loading the models. Latter on ill simply use raw vertice data for calclulations.
 

Edited by Sollum

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!