Skip to content

Geometry Processing and Visualization

Installation

All libraries (igl, meshplot, wildmeshing, polyfempy) can be installed from Conda forge with conda install -c conda-forge <lib>.

Import

import igl
import meshplot as mp
import numpy as np

Hello World

v, f = igl.read_triangle_mesh("data/bunny.obj")
mp.plot(v, f, v[:, 0])

Data Representation

Meshes are represented by a numpy array of vertex coordinates (nx3) and a numpy array of face indices (mx3) and can be loaded from 3D file formats.

v: np.array # Array of vertex coordinates (nx3)
f: np.array # Array of face indices (mx3)
v, f = igl.read_triangle_mesh("data/bunny.obj")
print(v)
print(f)
[[-0.0260146   0.112578    0.0363871 ]
 [-0.0321783   0.174119   -0.00263321]
 [-0.080718    0.152855    0.0302446 ]
 ...
 [-0.023099    0.156978   -0.00584018]
 [-0.0713101   0.15068    -0.0435721 ]
 [-0.0396435   0.152397   -0.00721968]]
[[2784 2497 2027]
 [1077  225 1060]
 [ 425  450  381]
 ...
 [3086 3203 3162]
 [3086 3162 3151]
 [3086 3151 3085]]

Visualizing Surfaces and Pointclouds

mp.plot(v, f, c=v[:, 0])
mp.plot(v, c=v[:, 0])

Scalar and Vector Field Visualization

# Calculating properties of the mesh
nf = igl.per_face_normals(v, f, np.array([0.0, 0.0, 0.0]))
nfv = np.linalg.norm(nf * 0.5 + 0.5, axis=1)
nv = igl.per_vertex_normals(v, f)
area = igl.doublearea(v, f)
avg = igl.avg_edge_length(v, f)

v1, v2, k1, k2 = igl.principal_curvature(v, f)
mean_curv = 0.5 * (k1 + k2)

# Face normals
d = mp.subplot(v, f, c=nfv, s=[2, 2, 0])

# Vertex normals as lines
mp.subplot(v, c=nv, s=[2, 2, 1], data=d)
d.rows[0][1].add_lines(v, v + nv * avg)

# Mean curvature + directions
mp.subplot(v, f, c=mean_curv, s=[2, 2, 2], data=d)
d.rows[1][0].add_lines(v + v1 * avg/3, v - v1 * avg/3, shading={"line_color": "red"})
d.rows[1][0].add_lines(v + v2 * avg/3, v - v2 * avg/3, shading={"line_color": "green"})

# Triangle area
mp.subplot(v, f, c=-area, s=[2, 2, 3], shading={"metalness": 0.0, "roughness": 1.0}, data=d)