# 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

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 on other sites

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 on other sites

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:

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

##### 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 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 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 on other sites

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.

Flipped models are also fixed, but there is small 0.000001 error

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

## Create an account

Register a new account

• 10
• 19
• 14
• 19
• 15
• ### 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.

• 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.