trimesh icon indicating copy to clipboard operation
trimesh copied to clipboard

Are Self Intersecting Meshes Volumes?

Open Eric-Vin opened this issue 11 months ago • 8 comments

Is a mesh considered a volume if it has self intersections? It doesn't seem like this is considered in the description of is_volume, but I've seen it used in other definitions. I've attached an example of a mesh that appears to have intersecting faces but is registered as a volume by Trimesh. table_mesh.zip

Eric-Vin avatar Jul 11 '23 17:07 Eric-Vin

I took a peek at the attached .obj in meshlab, and wasn't able to detect any self intersections

and, anyone feel free to correct me if this is inaccurate, but with respect to the is_volume question:

meshes are inherently a representation of 'inside' versus 'outside', so given consistent winding (no discontinuities wrt. 'inside' vs 'outside' between adjacent faces) and a mesh surface with no holes, the mesh will possess volumetric data

will the magnitude of that volume be particularly meaningful? I believe that depends on the calculation algorithm used, but in general it may not be a particularly useful thing to ask 'how much air is in this impossible balloon'

hope this is useful!

@mikedh do you think this could be closed?

caseymjohnson avatar Oct 26 '23 17:10 caseymjohnson

There are definitely intersecting faces in the Trimesh object, but I think the issue is that the Trimesh object actually contains multiple meshes, which intersect with each other (i.e. the different support beams). Since is_volume is called over the whole Trimesh object, I just wanted to know what the intended semantics were in this case.

As an example, here's some code that returns True on my machine using the above mesh, indicating the bodies/faces intersect:

mesh.split()[0].intersection(mesh.split()[8]).is_volume

Eric-Vin avatar Oct 26 '23 17:10 Eric-Vin

ah you're absolutely correct, I missed the funkiness at the corners

Screenshot 2023-10-26 at 1 49 30 PM

so looking at is_volume

valid = bool(
            self.is_watertight
            and self.is_winding_consistent
            and np.isfinite(self.center_mass).all()
            and self.volume > 0.0
        )

does this mean that an object of multiple mesh components is said to be a volume if all of the constituent components meet all four criteria?

just starting to dive into the nitty gritty of the code so I appreciate the insight :)

caseymjohnson avatar Oct 26 '23 17:10 caseymjohnson

At the moment this behavior seems undefined, but I think the example is not a manifold mesh which means that if someone passed it to an engine like Manifold, I assume it would reject it unless it has some mechanism to repair it. If the current is_volume semantics that you highlighted are what's desired (just checking that all mesh components are volumes), then it might be useful to add an is_manifold check that's stricter, though I don't know how we would implement that as there appear to be some tricky cases. @mikedh any thoughts?

Eric-Vin avatar Oct 26 '23 18:10 Eric-Vin

Just to add what a potential repair function could look like. The function could just split the submeshes by volumetric body and then union them together, but the current split() function just uses face adjacency so that won't work (if you split a hollow sphere you get two sets of faces back, the inner surface facing inwards and the outside surface facing outwards). I haven't looked too much into whether or not there's an easy way to do this volumetric decomposition.

Eric-Vin avatar Oct 26 '23 18:10 Eric-Vin

note that manifold does not have a way to check for self-intersections as of today, so we will not reject it but will get incorrect results (should still be a manifold, but geometrically incorrect)

pca006132 avatar Nov 02 '23 20:11 pca006132

That's good to know, thanks for the info @pca006132 !

Eric-Vin avatar Nov 03 '23 00:11 Eric-Vin

Sorry for the delayed response as I had no good answers haha. And thanks for all the work on manifold+bindings it is such a huge improvement over the previous stuff! As pointed out yeah is_volume is currently the all of these:

  • is_winding_consistant
    • Every edge appears exactly twice with reversed sign
  • is_watertight
    • Every edge appears exactly twice
  • np.isfinite(mesh.center_mass).all()
    • I don't remember why this was added, this may just be a re-statement of volume > 0 as it is "surface integral divided by volume." Maybe there are cases where the integral is also infinite?
  • volume > 0
    • i.e. inverted stuff has negative volume.

Currently is_volume is returning true for multibody meshes (which may or may not be reasonable). I'm definitely open to making is_volume stricter although it would be nice to avoid any super slow operations if possible.

Is a mesh considered a volume if it has self intersections?

I think this is tough: if the self-intersection avoids any vertex-vertex collisions it will currently return is_volume=True (i.e. like the pointy tail of a rabbit penetrates the rabbit body but none of the tail vertices interfere with the body vertices). I have no idea how you'd check for that case without it being incredibly slow, but if someone has a good idea I'm open to it! The naive way that comes to mind would be to test every edge against every face for edges that intersect faces outside of the face's boundary.

Checking for multi-body meshes is a lot easier, it currently uses mesh.edges_sparse which is a scipy.sparse.csgraph object and is pretty fast. We could just add a mesh.body_count == 1 to the list of checks if that was helpful:

In [9]: m = trimesh.creation.box(bounds = [[0,0,0],[1,1,1]]) + trimesh.creation.box(bounds=[[2,2,2],[3,3,3]])

In [10]: m.is_volume
Out[10]: True

In [11]: m.body_count
Out[11]: 2

In [12]: m.body_count?
Type:        property
String form: <property object at 0x7f9b9ffd3fb0>
Docstring:  
How many connected groups of vertices exist in this mesh.
Note that this number may differ from result in mesh.split,
which is calculated from FACE rather than vertex adjacency.

Returns
-----------
count : int
  Number of connected vertex groups

mikedh avatar Nov 07 '23 22:11 mikedh