Skip to content

Instantly share code, notes, and snippets.

@zishun
Last active January 12, 2024 07:00
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save zishun/0ba4f7925a1cd1ece890eb4dee4cd81e to your computer and use it in GitHub Desktop.
Save zishun/0ba4f7925a1cd1ece890eb4dee4cd81e to your computer and use it in GitHub Desktop.
# OpenMesh-Python Cheat Sheet
'''
documentation: https://openmesh-python.readthedocs.io/en/latest/
OpenMesh-Python official repository:
https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python
C++ documentation:
https://www.openmesh.org/media/Documentations/OpenMesh-Doc-Latest/a04099.html
Installation:
* pip install openmesh # https://pypi.org/project/openmesh/
* conda install -c conda-forge openmesh-python # https://anaconda.org/conda-forge/openmesh-python/
This is NOT https://anaconda.org/conda-forge/openmesh/
'''
import openmesh
# File IO
# file formats: obj, off, om, ply, stl, vtk (only write)
mesh = openmesh.read_trimesh('filename.obj') # or read_polymesh
# Options:
# binary, msb, lsb, swap,
# vertex_normal, vertex_color, vertex_tex_coord,
# halfedge_tex_coord, edge_color,
# face_normal, face_color, face_texture_index,
# color_alpha, color_float
# obj texture:
# texture_file="moon.png",
# material_file_extension=".mtl"
openmesh.write_mesh('filename.obj', mesh)
# The same options as read_trimesh, except for face_texture_index
# Geometry Elements and Standard Properties
mesh.n_vertices() # number of elements
mesh.n_edges()
mesh.n_faces()
mesh.n_halfedges()
point_array = mesh.points() # get element array
face_array = mesh.face_vertex_indices()
color_array = mesh.vertex_colors() # n x 4
mesh.vertex_normals()
mesh.vertex_texcoords1D() # vertex_texcoords2D vertex_texcoords3D
mesh.halfedge_normals()
mesh.halfedge_colors()
mesh.halfedge_texcoords1D() # halfedge_texcoords2D() halfedge_texcoords3D()
mesh.edge_colors()
mesh.face_normals()
mesh.face_colors()
# access vertex position, face index, normal, color, texcoord
vh0 = mesh.vertex_handle(0)
point = mesh.point(vh0)
eh0 = mesh.edge_handle(0)
heh = mesh.halfedge_handle(eh0, 0)
vh1 = mesh.from_vertex_handle(heh)
vh2 = mesh.to_vertex_handle(heh)
heh0 = mesh.prev_halfedge_handle(heh)
heh1 = mesh.next_halfedge_handle(heh)
heh0 = mesh.find_halfedge(vh1, vh2)
assert(heh0.is_valid())
assert(mesh.is_boundary(heh0))
mesh.set_color(vh1, [0., 0., 0., 1.])
mesh.set_texcoord2D(vh1, [0.5, 0.5])
mesh.set_normal(vh1, [0., 0., 0.])
mesh.update_normals()
mesh.update_face_normals()
mesh.update_vertex_normals()
mesh.update_halfedge_normals()
mesh.update_normal(vh0)
# seems unnecessary
mesh.has_vertex_normals()
# formats: mesh.<op>_<prop>()
# <op>: has / release / request
# <prop>:
# vertex_normals, vertex_colors, vertex_texcoords<n>D (n = 1,2,3)
# face_normals, face_colors, face_texture_index
# edge_colors
# halfedge_normals, halfedge_colors, halfedge_texcoords<n>D
# <ele>_status, <ele>: vertex, face, halfedge, edge
# Iterators and Circulators
for vh1 in mesh.vertices():
# iterate over the 1-ring of a vertex
[vh.idx() for vh in mesh.vv(vh1)]
# iterate over all incoming halfedges
[heh.idx() for heh in mesh.vih(vh1)]
# iterate over all outgoing halfedges
[heh.idx() for heh in mesh.voh(vh1)]
# iterate over all adjacent edges
[eh.idx() for eh in mesh.ve(vh1)]
# iterate over all adjacent faces
[fh.idx() for fh in mesh.vf(vh1)]
for heh in mesh.halfedges():
print(heh.idx())
for eh in mesh.edges():
print(eh.idx())
for fh0 in mesh.faces():
print(fh0.idx())
# iterate over the face's vertices
[vh.idx() for vh in mesh.fv(fh0)]
# iterate over the face's halfedges
[heh.idx() for heh in mesh.fh(fh0)]
# iterate over the face's edges
[eh.idx() for eh in mesh.fe(fh0)]
# iterate over all edge-neighboring faces
[fh.idx() for fh in mesh.ff(fh0)]
# indices
# vertex
indices = mesh.vv_indices() # or mesh.vertex_vertex_indices()
indices = mesh.vf_indices() # mesh.vertex_face_indices()
indices = mesh.ve_indices() # mesh.vertex_edge_indices()
indices = mesh.voh_indices() # mesh.vertex_outgoing_halfedge_indices()
indices = mesh.vih_indices() # mesh.vertex_incoming_halfedge_indices()
# face
indices = mesh.fv_indices() # mesh.face_vertex_indices()
indices = mesh.ff_indices() # mesh.face_face_indices()
indices = mesh.fe_indices() # mesh.face_edge_indices()
indices = mesh.fh_indices() # mesh.face_halfedge_indices()
# edge
indices = mesh.ev_indices() # mesh.edge_vertex_indices()
indices = mesh.ef_indices() # mesh.edge_face_indices()
indices = mesh.eh_indices() # mesh.edge_halfedge_indices()
# half edge
indices = mesh.hv_indices() # mesh.halfedge_vertex_indices()
indices = mesh.htv_indices() # mesh.halfedge_to_vertex_indices()
indices = mesh.hfv_indices() # mesh.halfedge_from_vertex_indices()
indices = mesh.hf_indices() # mesh.halfedge_face_indices()
indices = mesh.he_indices() # mesh.halfedge_edge_indices()
# Mesh Manipulation
# add/delete geometry elements
# add vertices/faces
mesh = openmesh.TriMesh()
vh0 = mesh.add_vertex([0, 1, 0])
vh1 = mesh.add_vertex([1, 0, 0])
vh2 = mesh.add_vertex([2, 1, 0])
fh0 = mesh.add_face([vh0, vh1, vh2]) # or fh0 = mesh.add_face(vh0, vh1, vh2)
# init with arrays
points = mesh.points()
face_vertex_indices = mesh.face_vertex_indices()
mesh = openmesh.PolyMesh(points, face_vertex_indices) # also openmesh.TriMesh
for vh in mesh.vertices():
mesh.delete_vertex(vh)
mesh.delete_face(fh0, delete_isolated_vertices=True)
mesh.garbage_collection()
if mesh.is_collapse_ok(heh0):
mesh.collapse(heh0)
if mesh.is_flip_ok(eh0):
mesh.flip(eh0)
mesh.split(eh0, vh0)
# https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python/tree/master/tests
@zishun
Copy link
Author

zishun commented May 14, 2021

Useful links:

@ifsheldon
Copy link

Thanks a lot! This is much useful than the Python API's documentation.

@PKRpng
Copy link

PKRpng commented Oct 21, 2021

Beware. Some of the functions do not work with the conda-forge version. It seems there are significant differences between the pip and conda versions

@alonrubintec
Copy link

This is awesome thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment