Open Eric-Vin opened 1 year ago
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?
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
ah you're absolutely correct, I missed the funkiness at the corners
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 :)
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?
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.
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)
That's good to know, thanks for the info @pca006132 !
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
is_watertight
np.isfinite(mesh.center_mass).all()
volume > 0
as it is "surface integral divided by volume." Maybe there are cases where the integral is also infinite?volume > 0
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
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