Jump to content
  • Advertisement

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
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By 4d3d
      Hi there,
      I've been away from 3d Art whilst on Maternity leave and just started to get an hour a day (if i'm lucky) to model while my baby sleeps. This is also my reason for picking something small. Really i'm after some feedback, good or bad, on any improvements, tips on rendering etc. 

      Any feedback would be massively appreciated as my time is so precious at the moment that i don't often have time to watch tutorials and research techniques so anything to point me in the right direction would be great.

      I've baked down from High-poly and exposed some custom color changing, decals, and number plate naming from substance designer and imported to marmoset.



    • By lucky6969b
      Dear folks,
      How do I calculate the axis of rotation between 2 vectors, one of them is the source directional vector, and the second is the destination directional vector.
      Thanks a lot
      Jack
    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By ChenMo
      I am implementing baking in our engine.I met a problem about how to assignment per object uv in lightmap atlas.
      I am using UVAtlas to generate lightmap uv, most unwrapped mesh has a uv range [0, 1), no matter how big they are. I wanna them have same uv density so to packing them well in lightmap atlas.I have tried thekla_atlas to do the same thing too, but it seems that it can not unwrap uv according mesh size.
      As far as I can see, unwrapping uv coordinates using its world space can solve this, all meshes share a same scale.But I don't hope to spend a lot of time to write these code and debug them.I am wandering is there exist some methods I don't know that can scale each lightmap uv to a same density.
      Thanks in advance. : )
  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!