PyMesh / PyMesh

Geometry Processing Library for Python
1.9k stars 365 forks source link

remove_isolated_vertices fails to remove isolated vertices #130

Closed dstoutamire closed 6 years ago

dstoutamire commented 6 years ago
import pymesh as pm

b = pm.generate_box_mesh((0,0,0), (10,10,10), subdiv_order=3)
b, info = pm.remove_isolated_vertices(b)

print('num_vertex_removed:', info['num_vertex_removed'])

for i in [5, 6, 7]:
    print('Here is %i:' % i)
    for j in range(b.faces.shape[0]):
        if b.faces[j,0]==i or b.faces[j,1]==i or b.faces[j,2]==i:
            print(b.faces[j])

This produces the output

num_vertex_removed: 0
Here is 5:
[5 0 1]
[5 4 0]
[10  5  1]
[19  4  5]
[22  5 10]
[22 19  5]
Here is 6:
Here is 7:
[0 7 3]
[0 4 7]
[ 3  7 15]
[ 4 21  7]
[ 7 25 15]
[ 7 21 25]

Vertex 6 should have been removed as there are no referencing faces.

dstoutamire commented 6 years ago

However, in this case remove_isolated_vertices_raw does work:

v, f, info = pm.remove_isolated_vertices_raw(b.vertices, b.faces)
b = pm.form_mesh(v, f)
...
num_vertex_removed: 343
Here is 5:
[5 0 1]
[5 4 0]
[9 5 1]
[15  4  5]
[17  5  9]
[17 15  5]
Here is 6:
[0 6 3]
[0 4 6]
[ 3  6 12]
[ 4 16  6]
[ 6 18 12]
[ 6 16 18]
Here is 7:
[1 8 7]
[9 1 7]
[ 7  8 20]
[ 7 20 19]
[21  9  7]
[21  7 19]
qnzhou commented 6 years ago

This is because pymesh.generate_box_mesh creates a volumetric mesh (i.e. b.voxels are not empty). So, the isolated vertices you found are actually interior vertices used by voxels. If you only need a surface mesh, you can form a new mesh from vertices and the faces only:

b = pm.generate_box_mesh((0,0,0), (10,10,10), subdiv_order=3)
b = pm.form_mesh(b.vertices, b.faces)  # Extract the surface mesh.
b, info = pm.remove_isolated_vertices(b)
dstoutamire commented 6 years ago

I see. The documentation does indeed make it clear that something special is going on with tets, unlike the other procedural mesh generators.