Local Mesh Cleanup¶
Meshes coming from the real world are rarely clean. Artifacts such as
degeneracies, duplicate vertex/triangles and self-intersections are rampant (See
the about
page in our Thingi10K dataset). Unfortunately, many geometry
processing operations have strict and often unspecified requirements on the
cleanness of the input geometry. Here, we provide a number of handy routines to
facilitate the task of cleaning up a mesh.
Remove isolated vertices¶
Isolated vertices are vertices not referred by any face or voxel. They often does not contribute to the geometry (except for the case of point cloud), and thus can be safely removed.
-
pymesh.
remove_isolated_vertices
(mesh)¶ Wrapper function of
remove_isolated_vertices_raw()
.Parameters: mesh ( Mesh
) – Input mesh.Returns: 2 values are returned. output_mesh
(Mesh
): Output mesh.infomation
(dict
): Adict
of additional informations.
The following fields are defined in
infomation
:num_vertex_removed
: Number of vertex removed.ori_vertex_index
: Original vertex index. That is vertexi
ofoutput_vertices
has indexori_vertex_index[i]
in the input vertex array.
-
pymesh.
remove_isolated_vertices_raw
(vertices, elements)¶ Remove isolated vertices.
Parameters: - vertices (
numpy.ndarray
) – Vertex array with one vertex per row. - elements (
numpy.ndarray
) – Element array with one face per row.
Returns: 3 values are returned.
output_vertices
: Output vertex array with one vertex per row.output_elements
: Output element array with one element per row.infomation
: Adict
of additional informations.
The following fields are defined in
infomation
:num_vertex_removed
: Number of vertex removed.ori_vertex_index
: Original vertex index. That is vertexi
ofoutput_vertices
has indexori_vertex_index[i]
in the input vertex array.
- vertices (
Remove duplicate vertices¶
Duplicate or near duplicate vertices are vertices with nearly same coordinates. Two vertices can be considered as duplicates of each other if their Euclidean distance is less than a tolerance (labeled tol). Duplicate vertices can often be merged into a single vertex.
-
pymesh.
remove_duplicated_vertices
(mesh, tol=1e-12, importance=None)¶ Wrapper function of
remove_duplicated_vertices_raw()
.Parameters: - mesh (
Mesh
) – Input mesh. - tol (
float
) – (optional) Vertices with distance less thantol
are considered as duplicates. Default is1e-12
. - importance (
numpy.ndarray
) – (optional) Per-vertex importance value. When discarding duplicates, the vertex with the highest importance value will be kept.
Returns: 2 values are returned.
output_mesh
(Mesh
): Output mesh.information
(dict
): Adict
of additional informations.
The following fields are defined in
information
:num_vertex_merged
: number of vertex merged.index_map
: An array that maps input vertex index to output vertex index. I.e. vertexi
will be mapped toindex_map[i]
in the output.
- mesh (
-
pymesh.
remove_duplicated_vertices_raw
(vertices, elements, tol=1e-12, importance=None)¶ Merge duplicated vertices into a single vertex.
Parameters: - vertices (
numpy.ndarray
) – Vertices in row major. - elements (
numpy.ndarray
) – Elements in row major. - tol (
float
) – (optional) Vertices with distance less thantol
are considered as duplicates. Default is1e-12
. - importance (
numpy.ndarray
) – (optional) Per-vertex importance value. When discarding duplicates, the vertex with the highest importance value will be kept.
Returns: 3 values are returned.
output_vertices
: Output vertices in row major.output_elements
: Output elements in row major.information
: Adict
of additional informations.
The following fields are defined in
information
:num_vertex_merged
: number of vertex merged.index_map
: An array that maps input vertex index to output vertex index. I.e. vertexi
will be mapped toindex_map[i]
in the output.
- vertices (
Collapse short edges¶
Short edges are edges with length less than a user specified threshold. Use the following functions to collapse all short edges in the mesh. The output mesh guarantees to have no short edges.
-
pymesh.
collapse_short_edges
(mesh, abs_threshold=0.0, rel_threshold=None, preserve_feature=False)¶ Wrapper function of
collapse_short_edges_raw()
.Parameters: - mesh (
Mesh
) – Input mesh. - abs_threshold (
float
) – (optional) All edge with length below or equal to this threshold will be collapsed. This value is ignored ifrel_thresold
is notNone
. - rel_threashold (
float
) – (optional) Relative edge length threshold based on average edge length. e.g.rel_threshold=0.1
means all edges with length less than0.1 * ave_edge_length
will be collapsed. - preserve_feature (
bool
) – True if shape features should be preserved. Default is false.
Returns: 2 values are returned.
output_Mesh
(Mesh
): Output mesh.information
(dict
): Adict
of additional informations.
The following attribute are defined:
face_sources
: The index of input source face of each output face.
The following fields are defined in
information
:num_edge_collapsed
: Number of edge collapsed.
- mesh (
-
pymesh.
collapse_short_edges_raw
(vertices, faces, abs_threshold=0.0, rel_threshold=None, preserve_feature=False)¶ Convenient function for collapsing short edges.
Parameters: - vertices (
numpy.ndarray
) – Vertex array. One vertex per row. - faces (
numpy.ndarray
) – Face array. One face per row. - abs_threshold (
float
) – (optional) All edge with length below or equal to this threshold will be collapsed. This value is ignored ifrel_thresold
is notNone
. - rel_threashold (
float
) – (optional) Relative edge length threshold based on average edge length. e.g.rel_threshold=0.1
means all edges with length less than0.1 * ave_edge_length
will be collapsed. - preserve_feature (
bool
) – True if shape features should be preserved. Default is false.
Returns: 3 values are returned.
output_vertices
: Output vertex array. One vertex per row.output_faces
: Output face array. One face per row.information
: Adict
of additional informations.
The following fields are defined in
information
:num_edge_collapsed
: Number of edge collapsed.source_face_index
: An array tracks the source of each output face. That is facei
of theoutput_faces
comes from facesource_face_index[i]
of the input faces.
- vertices (
Split long edges¶
Long edges are sometimes undesirable as well. Use the following functions to split long edges into 2 or more shorter edges. The output mesh guarantees to have no edges longer than the user specified threshold.
-
pymesh.
split_long_edges
(mesh, max_edge_length)¶ Wrapper function of
split_long_edges_raw()
.Parameters: - mesh (
Mesh
) – Input mesh. - max_edge_length (
float
) – Maximum edge length allowed. All edges longer than this will be split.
Returns: 2 values are returned.
output_mesh
(Mesh
): Output mesh.information
: A dummydict
that is currently empty. It is here to ensure consistent interface across the module.
- mesh (
-
pymesh.
split_long_edges_raw
(vertices, faces, max_edge_length)¶ Split long edges.
Parameters: - vertices (
numpy.ndarray
) – Vertex array with one vertex per row. - faces (
numpy.ndarray
) – Face array with one face per row. - max_edge_length (
float
) – Maximum edge length allowed. All edges longer than this will be split.
Returns: 3 values are returned.
output_vertices
: Output vertex array with one vertex per row.output_faces
: Output face array with one face per row.information
: A dummydict
that is currently empty. It is here to ensure consistent interface across the module.
- vertices (
Remove duplicate faces¶
Duplicate faces are faces consisting of the same vertices. They are often not desirable and may cause numerical problems. Use the following functions to remove them.
-
pymesh.
remove_duplicated_faces
(mesh, fins_only=False)¶ Wrapper function of
remove_duplicated_faces_raw()
.Parameters: - mesh (
Mesh
) – Input mesh. - fins_only (
bool
) – If set, only remove fins.
Returns: 2 values are returned.
output_mesh
(Mesh
): Output mesh.information
(dict
): Adict
of additional informations.
The following fields are defined in
information
:ori_face_index
: An array of original face indices. I.e. facei
of theoutput_faces
has indexori_face_index[i]
in the input vertices.
- mesh (
-
pymesh.
remove_duplicated_faces_raw
(vertices, faces, fins_only=False)¶ Remove duplicated faces.
Duplicated faces are defined as faces consist of the same set of vertices. Depending on the face orientation. A special case of duplicated faces is a fin. A fin is defined as two duplicated faces with opposite orientaiton.
If fins_only is set to True, all fins in the mesh are removed. The output mesh could still contain duplicated faces but no fins.
If fins_only is not True, all duplicated faces will be removed. There could be two caes:
If there is a dominant orientation, that is more than half of the faces are consistently orientated, and fins_only is False, one face with the dominant orientation will be kept while all other faces are removed.
If there is no dominant orientation, i.e. half of the face are positively orientated and the other half is negatively orientated, all faces are discarded.
Parameters: - vertices (
numpy.ndarray
) – Vertex array with one vertex per row. - faces (
numpy.ndarray
) – Face array with one face per row. - fins_only (
bool
) – If set, only remove fins.
Returns: 3 values are returned.
output_vertices
: Output vertex array, one vertex per row.output_faces
: Output face array, one face per row.information
: Adict
of additional informations.
The following fields are defined in
information
:ori_face_index
: An array of original face indices. I.e. facei
of theoutput_faces
has indexori_face_index[i]
in the input vertices.
- vertices (
Remove obtuse triangles¶
Obtuse triangles are often not desirable due to their geometric nature (e.g. circumcenter of obtuse triangles are outside of the triangle). Each obtuse triangle can always be split into 2 or more right or sharp triangles. They can be removed using the following routines.
-
pymesh.
remove_obtuse_triangles
(mesh, max_angle=120, max_iterations=5)¶ Wrapper function of
remove_obtuse_triangles_raw()
.Parameters: - mesh (
Mesh
) – Input mesh. - max_angle (
float
) – (optional) Maximum obtuse angle in degrees allowed. All triangle with larger internal angle would be split. Default is 120 degrees. - max_iterations (
int
) – (optional) Number of iterations to run before quitting. Default is 5.
Returns: 2 values are returned.
output_mesh
(Mesh
): Output mesh.information
(dict
): Adict
of additinal informations.
The following fields are defiend in
information
:num_triangle_split
: number of triangles split.
- mesh (
-
pymesh.
remove_obtuse_triangles_raw
(vertices, faces, max_angle=120, max_iterations=5)¶ Remove all obtuse triangles.
Parameters: - vetices (
numpy.ndarray
) – Vertex array with one vertex per row. - faces (
numpy.ndarray
) – Face array with one face per row. - max_angle (
float
) – (optional) Maximum obtuse angle in degrees allowed. All triangle with larger internal angle would be split. Default is 120 degrees. - max_iterations (
int
) – (optional) Number of iterations to run before quitting. Default is 5.
Returns: 3 values are returned.
output_vertices
: Output vertex array with one vertex per row.output_faces
: Output face array with one face per row.information
: Adict
of additinal informations.
The following fields are defiend in
information
:num_triangle_split
: number of triangles split.
- vetices (
Remove degenerate triangles¶
Degenerate triangles are triangles with collinear vertices. They have zero area and their normals are undefined. They can be removed using the following routines.
-
pymesh.
remove_degenerated_triangles
(mesh, num_iterations=5)¶ Wrapper function of
remove_degenerated_triangles_raw()
.Parameters: mesh ( Mesh
) – Input mesh.Returns: 2 values are returned. mesh
: AMesh
object without degenerated triangles.info
: Additional information dictionary.
-
pymesh.
remove_degenerated_triangles_raw
(vertices, faces, num_iterations=5)¶ Remove degenerated triangles.
Degenerated faces are faces with collinear vertices. It is impossible to compute face normal for them. This method get rid of all degenerated faces. No new vertices will be introduced. Only connectivity is changed.
Parameters: - vertices (
numpy.ndarray
) – Vertex array with one vertex per row. - faces (
numpy.ndarray
) – Face array with one triangle per row.
Returns: 3 values are returned.
output_vertices
: Output vertex array, one vertex per row.output_faces
: Output face array, one face per row.info
: Additional information dict.
- The following fields are defined in the
info
dict: ori_face_indices
: index array that maps each output face to an input face that contains it.
- vertices (
Self-intersections¶
Self-intersections are often a problem in geometry processing. They can be detected and resolved with the following routines.
-
pymesh.
detect_self_intersection
(mesh)¶ Detect all self-intersections.
Parameters: mesh ( Mesh
) – The input mesh.Returns: A n by 2 array of face indices. Each row contains the indices of two intersecting faces. \(n\) is the number of intersecting face pairs. Return type: numpy.ndarray
-
pymesh.
resolve_self_intersection
(mesh, engine='auto')¶ Resolve all self-intersections.
Parameters: - mesh (
Mesh
) – The input mesh. Only triangular mesh is supported. - engine (
string
) –(optional) Self-intersection engine. Valid engines include:
auto
: the default engine (default isigl
).igl
: libigl’s self-intersection engine
Returns: A triangular
Mesh
with all self-intersection resolved. The following per-face scalar field is defined:face_sources
: For each output face, this field specifies the index of the corresponding “source face” in the input mesh.
- mesh (
Separate mesh into disconnected components¶
-
pymesh.
separate_mesh
(mesh, connectivity_type='auto')¶ Split mesh into connected components.
Parameters: - mesh (
Mesh
) – Input mesh. - connectivity_type (
str
) –possible types are
auto
: Same asface
for surface mesh,voxel
for voxel mesh.vertex
: Group component based on vertex connectivity.face
: Group component based on face connectivity.voxel
: Group component based on voxel connectivity.
Returns: A list of meshes, each represent a single connected component. Each output component have the following attributes defined:
ori_vertex_index
: The input vertex index of each output vertex.ori_elem_index
: The input element index of each output element.
- mesh (
Merge multiple meshes¶
-
pymesh.
merge_meshes
(input_meshes)¶ Merge multiple meshes into a single mesh.
Parameters: input_meshes ( list
) – a list of inputMesh
objects.Returns: A Mesh
consists of all vertices, faces and voxels frominput_meshes
. The following mesh attributes are defined:vertex_sources
: Indices of source vertices from the input mesh.face_sources
: Indices of source faces from the input mesh if the output contains at least 1 face.voxel_sources
: Indices of source voxels from the input mesh if the output contains at least 1 voxel.
Submesh extraction¶
Sometimes, it is useful to extract a local region from a more complex mesh for
futher examination. pymesh.submesh()
is designed for this task.
-
pymesh.
submesh
(mesh, element_indices, num_rings)¶ Extract a subset of the mesh elements and forming a new mesh.
Parameters: - mesh (
Mesh
) – The input mesh. - element_indices (
numpy.ndarray
) – The indices of selected elements (faces/voxels). - num_rings (int) – The number of rings around the selected elements to extract.
Returns: A
Mesh
object only containing the selected elements and their local neighborhood up to num_rings rings. The output mesh contains the following attributes:- ori_face_index/ori_voxel_index: The original index of each element.
- ring: Index indicating which ring does each element belongs. The selected elements belongs to the 0-ring.
- mesh (