igl (core)¶
Python API reference for igl.
accumarray¶
Accumulate values V at subscripts S. Like MATLAB's accumarray.
Parameters
S— #S list of subscripts (integer indices)V— #S list of values
Returns
- A max(S)+1 list of accumulated (summed) values
Accumulate a constant value at subscripts S. Like MATLAB's accumarray.
Parameters
S— #S list of subscripts (integer indices)val— scalar value to accumulate at each subscript
Returns
- A max(S)+1 list of accumulated (summed) values
adjacency_list¶
Constructs the graph adjacency list for a given triangle mesh.
Parameters
F— #F by dim list of mesh facessorted— Boolean flag to sort adjacency counter-clockwise
Returns
- List of adjacent vertices for each vertex
adjacency_matrix¶
Constructs the adjacency matrix for a simplicial mesh.
Parameters
F— #F by dim matrix of mesh simplices
Returns
- A Sparse adjacency matrix of size max(F)+1 by max(F)+1
Constructs the adjacency matrix for a polygon mesh.
Parameters
I— Vectorized list of polygon corner indices into rows of some matrix VC— Cumulative polygon sizes such that C(i+1)-C(i) = size of the ith polygon
Returns
- A Sparse adjacency matrix of size max(I)+1 by max(I)+1
all_pairs_distances¶
Compute distances between each point i in V and point j in U D = all_pairs_distances(V,U) @tparam matrix class like MatrixXd
Parameters
V— #V by dim list of pointsU— #U by dim list of pointssquared— whether to return squared distancesD— #V by #U matrix of distances, where D(i,j) gives the distance or squareed distance between V(i,:) and U(j,:)
arap_precomputation¶
arap_precomputation(V: float64[m, n], F: int64[m, n], dim: int, b: int32[m], data: ARAPData) -> None
arap_solve¶
average_from_edges_onto_vertices¶
average_from_edges_onto_vertices(F: int64[m, n], E: int64[m, n], oE: int64[m, n], uE: float64[m]) -> float64[m]
Move a scalar field defined on edges to vertices by averaging
Parameters
F— #F by 3 triangle mesh connectivityE— #E by 3 mapping from each halfedge to each edgeoE— #E by 3 orientation as generated by orient_halfedgesuE— #E by 1 list of scalarsuV— #V by 1 list of scalar defined on vertices
average_onto_faces¶
Move a scalar field defined on faces to faces by averaging
Parameters
F— #F by 3 triangle mesh connectivityS— #F by 1 scalar field defined on facesSF— #F by 1 scalar field defined on faces
average_onto_vertices¶
Move a scalar field defined on faces to vertices by averaging
Parameters
S— #V by dim triangle mesh connectivityF— #F by 3 triangle mesh connectivityS— #F by 1 scalar field defined on facesSV— #V by 1 scalar field defined on vertices
avg_edge_length¶
Constructs the cotangent stiffness matrix (discrete laplacian) for a given mesh (V,F).
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by simplex_size list of mesh elements (triangles or tetrahedra)L— #V by #V cotangent matrix, each row i corresponding to V(i,:)
barycenter¶
Computes the barycenter of every simplex.
Parameters
V— #V x dim matrix of vertex coordinatesF— #F x simplex_size matrix of indices of simplex corners into VBC— #F x dim matrix of 3d vertices
barycentric_coordinates¶
barycentric_coordinates(P: float64[m, n], A: float64[m, n], B: float64[m, n], C: float64[m, n]) -> float64[m, n]
Compute barycentric coordinates of each point in a corresponding triangle
Parameters
P— #P by 3 Query points in 3dA— #P by 3 Tri corners in 3dB— #P by 3 Tri corners in 3dC— #P by 3 Tri corners in 3dL— #P by 3 list of barycentric coordinates
barycentric_coordinates(P: float64[m, n], A: float64[m, n], B: float64[m, n], C: float64[m, n], D: float64[m, n]) -> float64[m, n]
Compute barycentric coordinates of each point in a corresponding tetrhedron
Parameters
P— #P by 3 Query points in 3dA— #P by 3 Tet corners in 3dB— #P by 3 Tet corners in 3dC— #P by 3 Tet corners in 3dD— #P by 3 Tet corners in 3dL— #P by 3 list of barycentric coordinates
barycentric_interpolation¶
barycentric_interpolation(D: float64[m, n], F: int64[m, n], B: float64[m, n], I: int64[m, n]) -> float64[m, n]
Interpolate per-vertex data on a triangle mesh using barycentric coordinates.
Parameters
D— #V by dim list of per-vertex dataF— #F by 3 list of triangle indicesB— #X by 3 list of barycentric coordinatesI— #X list of triangle indices into F
Returns
- X #X by dim list of interpolated data
bbw¶
bbw(V: float64[m, n], Ele: int64[m, n], b: int64[m], bc: float64[m, n], W0: float64[m, n] = Ellipsis, partition_unity: bool = False, verbosity: int = 0, max_iter: int = 100, inactive_threshold: float = 1e-14, constraint_threshold: float = 1e-14, solution_diff_threshold: float = 1e-14) -> float64[m, n]
Compute Bounded Biharmonic Weights on a given domain (V,Ele) with a given set of boundary conditions
@tparam DerivedV derived type of eigen matrix for V (e.g. MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. MatrixXi) @tparam Derivedb derived type of eigen matrix for b (e.g. VectorXi) @tparam Derivedbc derived type of eigen matrix for bc (e.g. MatrixXd) @tparam DerivedW derived type of eigen matrix for W (e.g. MatrixXd)
Parameters
V— #V by dim vertex positionsEle— #Elements by simplex-size list of element indicesb— #b boundary indices into Vbc— #b by #W list of boundary valuesdata— object containing options, initial guess --> solution and resultsW— #V by #W list of unnormalized weights to normalize use igl::normalize_row_sums(W,W)
bezier¶
Evaluate a polynomial Bezier curve at a single parameter value.
Parameters
V— #V by dim list of Bezier control pointst— evaluation parameter in [0,1]
Returns
- P 1 by dim output point
Evaluate a polynomial Bezier curve at many parameter values.
Parameters
V— #V by dim list of Bezier control pointsT— #T list of evaluation parameters in [0,1]
Returns
- P #T by dim output points
bfs_orient¶
Consistently orient faces in orientable patches using BFS.
Parameters
F— #F by 3 list of facesFF— #F by 3 list of faces (OK if same as F)C— #F list of component ids
biharmonic_coordinates¶
biharmonic_coordinates(V: float64[m, n], T: int64[m, n], S: Sequence[Sequence[int]], k: int = 2) -> float64[m, n]
Compute "discrete biharmonic generalized barycentric coordinates" as
described in "Linear Subspace Design for Real-Time Shape Deformation"
[Wang et al. 2015]. Not to be confused with "Bounded Biharmonic Weights
for Real-Time Deformation" [Jacobson et al. 2011] or "Biharmonic
Coordinates" (2D complex barycentric coordinates) [Weber et al. 2012].
These weights minimize a discrete version of the squared Laplacian energy
subject to positional interpolation constraints at selected vertices
(point handles) and transformation interpolation constraints at regions
(region handles).
@tparam SType should be a simple index type e.g. int,size_t
Parameters
V— #V by dim list of mesh vertex positionsT— #T by dim+1 list of / triangle indices into V if dim=2 \ tetrahedron indices into V if dim=3S— #point-handles+#region-handles list of lists of selected vertices for each handle. Point handles should have singleton lists and region handles should have lists of size at least dim+1 (and these points should be in general position).W— #V by #points-handles+(#region-handles * dim+1) matrix of weights so that columns correspond to each handles generalized barycentric coordinates (for point-handles) or animation space weights (for region handles).
Returns
- true only on success
bijective_composite_harmonic_mapping¶
bijective_composite_harmonic_mapping(V: float64[m, n], F: int64[m, n], b: int64[m], bc: float64[m, n], min_steps: int = 1, max_steps: int = 200, num_inner_iters: int = 20, test_for_flips: bool = True) -> float64[m, n]
Compute a injective planar mapping of a triangulated polygon (V,F) subjected to boundary conditions (b,bc). The mapping should be bijective in the sense that no triangles' areas become negative (this assumes they started positive). This mapping is computed by "composing" harmonic mappings between incremental morphs of the boundary conditions. This is a bit like a discrete version of "Bijective Composite Mean Value Mappings" [Schneider et al. 2013] but with a discrete harmonic map (cf. harmonic coordinates) instead of mean value coordinates. This is inspired by "Embedding a triangular graph within a given boundary" [Xu et al. 2011].
Parameters
V— #V by 2 list of triangle mesh vertex positionsF— #F by 3 list of triangle indices into Vb— #b list of boundary indices into Vbc— #b by 2 list of boundary conditions corresponding to bmin_steps— minimum number of steps to take from V(b,:) to bcmax_steps— minimum number of steps to take from V(b,:) to bc (if max_steps == min_steps then no further number of steps will be tried)num_inner_iters— number of iterations of harmonic solves to run after for each morph step (to try to push flips back in)test_for_flips— whether to check if flips occurred (and trigger more steps). if test_for_flips = false then this function always returns trueU— #V by 2 list of output mesh vertex locations
Returns
- true if and only if U contains a successful bijectie mapping
blue_noise¶
blue_noise(V: float64[m, n], F: int64[m, n], r: float) -> tuple[float64[m, n], int64[m], float64[m, n]]
"Fast Poisson Disk Sampling in Arbitrary Dimensions" [Bridson 2007]. For very dense samplings this is faster than (up to 2x) cyCodeBase's implementation of "Sample Elimination for Generating Poisson Disk Sample Sets" [Yuksel 2015]. YMMV
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh triangle indices into rows of Vr— Poisson disk radius (evaluated according to Euclidean distance on V)B— #P by 3 list of barycentric coordinates, ith row are coordinates of ith sampled point in face FI(i)FI— #P list of indices into FP— #P by dim list of sample positions.
boundary_facets¶
Determine boundary faces (edges) of tetrahedra (triangles) stored in T
(analogous to qptoolbox's outline and boundary_faces).
Parameters
T— tetrahedron (triangle) index list, m by 4 (3), where m is the number of tetrahedraF— list of boundary faces, n by 3 (2), where n is the number of boundary faces. Faces are oriented so that igl::centroid(V,F,…) computes the same sign volume as igl::volume(V,T)J— list of indices into T, n by 1K— list of indices revealing across from which vertex is this facet
boundary_loop¶
Compute the ordered boundary loop with the most vertices for a manifold mesh.
Parameters
F— #F by dim list of mesh facesL— ordered list of boundary vertices of longest boundary loop
boundary_loop_all¶
Compute all ordered boundary loops for a manifold mesh.
Parameters
F— #F by dim list of mesh faces
Returns
- List of lists of boundary vertices, where each sublist represents a loop
bounding_box¶
Build a triangle mesh of the bounding box of a given list of vertices
Parameters
V— #V by dim list of rest domain positionspad— padding offsetBV— 2^dim by dim list of bounding box corners positionsBF— #BF by dim list of simplex facets
bounding_box_diagonal¶
Compute the length of the diagonal of a given meshes axis-aligned bounding
Parameters
V— #V by 3 list of vertex/point positions
Returns
- length of bounding box diagonal
centroid¶
Computes the centroid and enclosed volume of a closed mesh using a surface integral.
Parameters
V— #V by dim list of rest domain positionsF— #F by 3 list of triangle indices into V
Returns
- c dim vector of centroid coordinates
- vol total volume of solid
circulation¶
circulation(e: int, ccw: bool, F: int64[m, n], EMAP: int64[m], EF: int64[m, n], EI: int64[m, n]) -> tuple[list[int], list[int]]
Return lists of "next" vertex indices (Nv) and face indices (Nf) for circulation.
Parameters
e— index of edge to circulateccw— circulate in ccw directionF— #F by 3 list of mesh facesEMAP— #F*3 list of indices mapping each directed edge to a unique edge in EEF— #E by 2 list of edge flapsEI— #E by 2 list of edge flap corners
Returns
- Tuple containing Nv (next vertex indices) and Nf (face indices)
circumradius¶
Compute the circumradius of each triangle in a mesh (V,F)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of triangle indices into VR— #F list of circumradiusR— #T list of circumradiusC— #T by dim list of circumcenterB— #T by simplex-size list of barycentric coordinates of circumcenter
collapse_edge¶
collapse_edge(e: int, p: float64[m], V: float64[m, n], F: int64[m, n], E: int64[m, n], EMAP: int64[m], EF: int64[m, n], EI: int64[m, n]) -> tuple[int, int, int, int]
Attempt to collapse a given edge of a mesh. Assumes (V,F) is a closed manifold mesh (except for previously collapsed faces which should be set to: [IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL]. Collapses exactly two faces and exactly 3 edges from E (e and one side of each face gets collapsed to the other). This is implemented in a way that it can be repeatedly called until satisfaction and then the garbage in F can be collected by removing NULL faces.
Parameters
e— index into E of edge to try to collapse. E(e,:) = [s d] or [d s] so that s<d, then d is collapsed to s.p— dim list of vertex position where to place merged vertex [mesh inputs]V— #V by dim list of vertex positions, lesser index of E(e,:) will be set to midpoint of edge.F— #F by 3 list of face indices into V.E— #E by 2 list of edge indices into V.EMAP— #F*3 list of indices into E, mapping each directed edge to unique unique edge in EEF— #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) " e=(j->i)EI— #E by 2 list of edge flap corners (see above). [mesh inputs]e1— index into E of edge collpased on lefte2— index into E of edge collpased on rightf1— index into F of face collpased on leftf2— index into F of face collpased on right
Returns
- true if edge was collapsed Because there are side-effects on V,F,E,EMAP,EF,EI, this function will not accept all numpy variations and will refuse to copy inputs that don't match expected ordering and dtype.
colormap¶
Map scalar values to RGB colors using a colormap.
Parameters
cm— colormap type (igl.ColorMapType.VIRIDIS, .JET, etc.)Z— #Z list of scalar valuesnormalize— if true, normalize Z to [0,1] range before mapping
Returns
- C #Z by 3 list of RGB colors in [0,1]
Map a single scalar in [0,1] to an RGB color.
Parameters
cm— colormap typef— scalar in [0,1]
Returns
- 3-vector of RGB values in [0,1]
comb_cross_field¶
comb_cross_field(V: float64[m, n], F: int64[m, n], PD1: float64[m, n], PD2: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Computes principal matchings of the vectors of a cross field across face edges, and generates a combed cross field defined on the mesh faces
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 4 eigen Matrix of face (quad) indicesPD1in— #F by 3 eigen Matrix of the first per face cross field vectorPD2in— #F by 3 eigen Matrix of the second per face cross field vectorPD1out— #F by 3 eigen Matrix of the first combed cross field vectorPD2out— #F by 3 eigen Matrix of the second combed cross field vector
comb_frame_field¶
comb_frame_field(V: float64[m, n], F: int64[m, n], PD1: float64[m, n], PD2: float64[m, n], BIS1_combed: float64[m, n], BIS2_combed: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Computes principal matchings of the vectors of a frame field across face edges, and generates a combed frame field defined on the mesh faces. This makes use of a combed cross field generated by combing the field created by the bisectors of the frame field.
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 4 eigen Matrix of face (quad) indicesPD1— #F by 3 eigen Matrix of the first per face cross field vectorPD2— #F by 3 eigen Matrix of the second per face cross field vectorBIS1_combed— #F by 3 eigen Matrix of the first combed bisector field vectorBIS2_combed— #F by 3 eigen Matrix of the second combed bisector field vectorPD1_combed— #F by 3 eigen Matrix of the first combed cross field vectorPD2_combed— #F by 3 eigen Matrix of the second combed cross field vector
combine¶
combine(VV: Sequence[float64[m, n]], FF: Sequence[int64[m, n]]) -> tuple[float64[m, n], int64[m, n]]
Concatenate multiple meshes into a single mesh.
Parameters
VV— list of vertex position matrices, each #Vi by dimFF— list of face index matrices, each #Fi by simplex_size
Returns
- V concatenated vertex positions
- F concatenated face indices (reindexed into V)
compute_frame_field_bisectors¶
compute_frame_field_bisectors(V: float64[m, n], F: int64[m, n], B1: float64[m, n], B2: float64[m, n], PD1: float64[m, n], PD2: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Compute bisectors of a frame field defined on mesh faces.
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 3 eigen Matrix of face (triangle) indicesB1— #F by 3 eigen Matrix of face (triangle) base vector 1B2— #F by 3 eigen Matrix of face (triangle) base vector 2PD1— #F by 3 eigen Matrix of the first per face frame field vectorPD2— #F by 3 eigen Matrix of the second per face frame field vectorBIS1— #F by 3 eigen Matrix of the first per face frame field bisectorBIS2— #F by 3 eigen Matrix of the second per face frame field bisector
compute_frame_field_bisectors(V: float64[m, n], F: int64[m, n], PD1: float64[m, n], PD2: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Compute bisectors of a frame field defined on mesh faces.
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 3 eigen Matrix of face (triangle) indicesPD1— #F by 3 eigen Matrix of the first per face frame field vectorPD2— #F by 3 eigen Matrix of the second per face frame field vectorBIS1— #F by 3 eigen Matrix of the first per face frame field bisectorBIS2— #F by 3 eigen Matrix of the second per face frame field bisector
connected_components¶
Determine the connected components of a graph described by the input adjacency matrix.
Parameters
A— #A by #A adjacency matrix (treated as describing a directed graph)C— (if return_C=True) #A list of component indices in [0,#K-1]K— (if return_K=True) #K list of sizes of each component
Returns
- number of connected components
cotmatrix¶
Constructs the cotangent stiffness matrix (discrete laplacian) for a given mesh (V,F).
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by simplex_size list of mesh elements (triangles or tetrahedra)L— #V by #V cotangent matrix, each row i corresponding to V(i,:)
cotmatrix(V: float64[m, n], I: int64[m], C: int64[m]) -> tuple[scipy.sparse.csc_matrix[float], scipy.sparse.csc_matrix[float], scipy.sparse.csc_matrix[float]]
Cotangent Laplacian (and mass matrix) for polygon meshes according to "Polygon Laplacian Made Simple" [Bunge et al.\ 2020]
Parameters
V— #V by 3 list of mesh vertex positionsI— #I vectorized list of polygon corner indices into rows of some matrix VC— #polygons+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of the ith polygonL— #V by #V polygon Laplacian made simple matrixM— #V by #V mass matrixP— #V+#polygons by #V prolongation operator
cotmatrix_entries¶
Compute the cotangent contributions for each angle in a mesh.
Parameters
V— #V by dim matrix of vertex positionsF— #F by {3|4} matrix of {triangle|tetrahedra} indices into V (optional)
Returns
- C #F by {3|6} matrix of cotangent contributions - For triangles, columns correspond to edges [1,2], [2,0], [0,1] - For tets, columns correspond to edges [1,2], [2,0], [0,1], [3,0], [3,1], [3,2]
Compute the cotangent contributions for each angle in a mesh.
Parameters
l— #F by 3 matrix of triangle edge lengths (optional, alternative to F)
Returns
- C #F by {3|6} matrix of cotangent contributions - For triangles, columns correspond to edges [1,2], [2,0], [0,1] - For tets, columns correspond to edges [1,2], [2,0], [0,1], [3,0], [3,1], [3,2]
cotmatrix_intrinsic¶
Constructs the cotangent stiffness matrix (discrete laplacian) for a given mesh with faces F and edge lengths l.
Parameters
l— #F by 3 list of (half-)edge lengthsF— #F by 3 list of face indices into some (not necessarily determined/embedable) list of vertex positions V. It is assumed #V == F.maxCoeff()+1L— #V by #V sparse Laplacian matrix
cross_field_mismatch¶
cross_field_mismatch(V: float64[m, n], F: int64[m, n], PD1: float64[m, n], PD2: float64[m, n], isCombed: bool) -> int64[m, n]
Calculates the mismatch (integer), at each face edge, of a cross field defined on the mesh faces. The integer mismatch is a multiple of pi/2 that transforms the cross on one side of the edge to the cross on the other side. It represents the deviation from a Lie connection across the edge.
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 3 eigen Matrix of face (quad) indicesPD1— #F by 3 eigen Matrix of the first per face cross field vectorPD2— #F by 3 eigen Matrix of the second per face cross field vectorisCombed— boolean, specifying whether the field is combed (i.e. matching has been precomputed. If not, the field is combed first.mismatch— #F by 3 eigen Matrix containing the integer mismatch of the cross field across all face edges
crouzeix_raviart_cotmatrix¶
crouzeix_raviart_cotmatrix(V: float64[m, n], F: int64[m, n], E: int64[m, n], EMAP: int64[m]) -> scipy.sparse.csc_matrix[float]
Compute the Crouzeix-Raviart cotangent stiffness matrix. See for example "Discrete Quadratic Curvature Energies" [Wardetzky, Bergou, Harmon, Zorin, Grinspun 2007]
Parameters
V— #V by dim list of vertex positionsF— #F by 3/4 list of triangle/tetrahedron indicesE— #E by 2/3 list of edges/facesEMAP— #F*3/4 list of indices mapping allE to EL— #E by #E edge/face-based diagonal cotangent matrix
crouzeix_raviart_massmatrix¶
crouzeix_raviart_massmatrix(V: float64[m, n], F: int64[m, n], E: int64[m, n], EMAP: int64[m]) -> scipy.sparse.csc_matrix[float]
CROUZEIX_RAVIART_MASSMATRIX Compute the Crouzeix-Raviart mass matrix where M(e,e) is just the sum of the areas of the triangles on either side of an edge e. See for example "Discrete Quadratic Curvature Energies" [Wardetzky, Bergou, Harmon, Zorin, Grinspun 2007]
Parameters
V— #V by dim list of vertex positionsF— #F by 3/4 list of triangle/tetrahedron indicesE— #E by 2/3 list of edges/facesEMAP— #F*3/4 list of indices mapping allE to EM— #E by #E edge/face-based diagonal mass matrix
cubic¶
Evaluate a cubic Bézier curve defined by control points C at parameter t.
Parameters
C— 4 by dim matrix of control points for a cubic Bézier curvet— parameter at which to evaluate the curve
Returns
- P 1 by dim point on the curve C(t)
cubic_is_flat¶
Test whether a cubic Bézier curve is flat within a given tolerance.
"Piecewise Linear Approximation of Bézier Curves" [Fischer 2000]. If the test passes, the curve's maximum squared distance to the chord from its first to its last control point is less than squared_distance_bound.
Parameters
C— 4 by dim matrix of control points for a cubic Bézier curvesquared_distance_bound— squared distance tolerance
Returns
- True if the curve is flat within the given tolerance
cubic_monomial_bases¶
Compute monomial basis representations for a cubic Bézier curve.
Parameters
C— 4 by dim matrix of control points for a cubic Bézier curve
Returns
- Tuple (M, D, B) where M 4 by dim matrix of monomial coefficients for C(t) D 3 by dim matrix of monomial coefficients for dC/dt B 6-vector of inner products of those basis functions for C(t)
cubic_split¶
Split a cubic Bézier curve at parameter t into two cubic Bézier curves.
Parameters
C— 4 by dim matrix of control points for a cubic Bézier curvet— parameter at which to split the curve
Returns
- Tuple (C1, C2) where C1 4 by dim control points of the sub-curve from C(0) to C(t) C2 4 by dim control points of the sub-curve from C(t) to C(1)
curved_hessian_energy¶
Computes the curved Hessian energy using the Crouzeix-Raviart discretization. See Oded Stein, Alec Jacobson, Max Wardetzky, Eitan Grinspun, 2020. "A Smoothness Energy without Boundary Distortion for Curved Surfaces"
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh elements (must be triangles)Q— #V by #V Hessian energy matrix, each row/column i corresponding to V(i,:
cut_mesh¶
cut_mesh(V: float64[m, n], F: int64[m, n], C: bool[m, n]) -> tuple[float64[m, n], int64[m, n], int64[m]]
Given a mesh and a list of edges that are to be cut, the function generates a new disk-topology mesh that has the cuts at its boundary.
\note Assumes mesh is edge-manifold.
Parameters
V— #V by 3 list of the vertex positionsF— #F by 3 list of the facescuts— #F by 3 list of boolean flags, indicating the edges that need to be cut (has 1 at the face edges that are to be cut, 0 otherwise)Vn— #V by 3 list of the vertex positions of the cut mesh. This matrix will be similar to the original vertices except some rows will be duplicated.Fn— #F by 3 list of the faces of the cut mesh(must be triangles). This matrix will be similar to the original face matrix except some indices will be redirected to point to the newly duplicated vertices.I— #V by 1 list of the map between Vn to original V index.
cut_mesh_from_singularities¶
Given a mesh (V,F) and the integer mismatch of a cross field per edge (mismatch), finds the cut_graph connecting the singularities (seams) and the degree of the singularities singularity_index
Parameters
V— #V by 3 list of mesh vertex positionsF— #F by 3 list of facesmismatch— #F by 3 list of per corner integer mismatchseams— #F by 3 list of per corner booleans that denotes if an edge is a seam or not
cut_to_disk¶
Given a triangle mesh, computes a set of edge cuts sufficient to carve the mesh into a topological disk, without disconnecting any connected components. Nothing else about the cuts (including number, total length, or smoothness) is guaranteed to be optimal. Simply-connected components without boundary (topological spheres) are left untouched (delete any edge if you really want a disk). All other connected components are cut into disks. Meshes with boundary are supported; boundary edges will be included as cuts.
The cut mesh itself can be materialized using cut_mesh().
Implements the triangle-deletion approach described by Gu et al's "Geometry Images."
@tparam Index Integrable type large enough to represent the total number of faces and edges in the surface represented by F, and all entries of F.
Parameters
F— #F by 3 list of the faces (must be triangles)cuts— List of cuts. Each cut is a sequence of vertex indices (where pairs of consecutive vertices share a face), is simple, and is either a closed loop (in which the first and last indices are identical) or an open curve. Cuts are edge-disjoint.
cylinder¶
Construct a triangle mesh of a cylinder (without caps)
Parameters
axis_devisions— number of vertices around the cylinderheight_devisions— number of vertices up the cylinderV— #V by 3 list of mesh vertex positionsF— #F by 3 list of triangle indices into V
decimate¶
decimate(V: float64[m, n], F: int32[m, n], max_m: int = 0, block_intersections: bool = False) -> tuple[float64[m, n], int64[m, n], int64[m], int64[m]]
Assumes (V,F) is a manifold mesh (possibly with boundary) collapses edges until desired number of faces is achieved. This uses default edge cost and merged vertex placement functions {edge length, edge midpoint}.
See \fileinfo for more details.
Parameters
V— #V by dim list of vertex positionsF— #F by 3 list of face indices into V.max_m— desired number of output facesblock_intersections— whether to block intersections (see intersection_blocking_collapse_edge_callbacks)U— #U by dim list of output vertex posistions (can be same ref as V)G— #G by 3 list of output face indices into U (can be same ref as G)J— #G list of indices into F of birth faceI— #U list of indices into V of birth vertices
Returns
- true if m was reached (otherwise #G > m)
dihedral_angles¶
Compute dihedral angles for all tets of a given tet mesh (V,T).
Parameters
V— #V by dim list of vertex positionsT— #V by 4 list of tet indicestheta— #T by 6 list of dihedral angles (in radians)cos_theta— #T by 6 list of cosine of dihedral angles (in radians)
dihedral_angles_intrinsic¶
dihedral_angles_intrinsic(A: float64[m, n], L: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Compute dihedral angles for all tets of a given tet mesh's intrinsics.
Parameters
V— #V by dim list of vertex positionsT— #V by 4 list of tet indicestheta— #T by 6 list of dihedral angles (in radians)cos_theta— #T by 6 list of cosine of dihedral angles (in radians)
dijkstra¶
dijkstra(V: float64[m, n], VV: Sequence[Sequence[int]], source: int, targets: Set[int]) -> tuple[float64[m], int64[m]]
Dijkstra shortest paths using Euclidean edge weights.
Parameters
V— #V by 3 list of vertex positionsVV— #V list of adjacency lists (e.g. from adjacency_list)source— source vertex indextargets— set of target vertex indices (stop early if reached)
Returns
- min_distance #V list of minimum distances from source
- previous #V list of previous vertex indices for path reconstruction
dijkstra(source: int, targets: Set[int], VV: Sequence[Sequence[int]], weights: Sequence[float]) -> tuple[float64[m], int64[m]]
Dijkstra shortest paths with custom vertex weights.
Parameters
source— source vertex indextargets— set of target vertex indicesVV— #V list of adjacency listsweights— #V list of vertex weights
Returns
- min_distance #V list of minimum distances from source
- previous #V list of previous vertex indices
dijkstra_backtrack¶
Backtrack path from a vertex to the source using Dijkstra's previous array.
Parameters
vertex— destination vertexprevious— #V list of previous vertex indices (from dijkstra)
Returns
- path list of vertex indices from vertex to source
directed_edge_parents¶
Recover parent edges in a tree given directed edges.
Parameters
E— #E by 2 list of directed edges
Returns
- P #E list of parent indices into E (-1 means root)
doublearea¶
Computes twice the area for each input triangle or quad.
Parameters
V— eigen matrix #V by 3F— #F by (3|4) list of mesh face indices into rows of VdblA— #F list of triangle double areas
doublearea(A: float64[m, n] = Ellipsis, B: float64[m, n] = Ellipsis, C: float64[m, n] = Ellipsis) -> float64[m]
Computes twice the area for each input triangle or quad.
Parameters
A— #F by dim list of triangle corner positionsB— #F by dim list of triangle corner positionsC— #F by dim list of triangle corner positionsdblA— #F list of triangle double areas
Computes twice the area for each input triangle or quad.
Parameters
l— #F by dim list of edge lengths using for triangles, columns correspond to edges 23,31,12nan_replacement— what value should be used for triangles whose given edge lengths do not obey the triangle inequality. These may be very wrong (e.g., [100 1 1]) or may be nearly degenerate triangles whose floating point side length computation leads to breach of the triangle inequality. One may wish to set this parameter to 0 if side lengths l are known to come from a valid embedding (e.g., some mesh (V,F)). In that case, the only circumstance the triangle inequality is broken is when the triangle is nearly degenerate and floating point error dominates: hence replacing with zero is reasonable.dblA— #F list of triangle double areas
ears¶
Find all ears (faces with two boundary edges) in a given mesh
Parameters
F— #F by 3 list of triangle mesh indicesears— #ears list of indices into F of earsear_opp— #ears list of indices indicating which edge is non-boundary (connecting to flops)
edge_flaps¶
Determine edge flaps with precomputed unique edge map and edge-face adjacency.
Parameters
F— #F by 3 list of face indicesuE— #uE by 2 list of unique edge indicesEMAP— #F*3 list of indices mapping each directed edge to unique edge in uE
Returns
- Tuple containing EF and EI matrices, where: EF - #E by 2 list of edge flaps EI - #E by 2 list of edge flap corners
Determine edge flaps, unique edge map, and edge-face adjacency from face list only.
Parameters
F— #F by 3 list of face indices
Returns
- Tuple containing uE, EMAP, EF, and EI where: uE - #uE by 2 list of unique edge indices EMAP - #F*3 list mapping each directed edge to unique edge in uE EF - #E by 2 list of edge flaps EI - #E by 2 list of edge flap corners
edge_lengths¶
Constructs a list of lengths of edges opposite each index in a face (triangle/tet) list.
Parameters
V— eigen matrix #V by 3F— #F by (2|3|4) list of mesh simplex indices into rows of VL— #F by {1|3|6} list of edge lengths - For edges, column of lengths - For triangles, columns correspond to edges [1,2],[2,0],[0,1] - For tets, columns correspond to edges [3 0],[3 1],[3 2],[1 2],[2 0],[0 1]
edge_topology¶
Initialize edges and their topological relations for an edge-manifold mesh.
Parameters
V— #V by dim list of vertex positions (unused, kept for API compatibility)F— #F by 3 list of triangle indices
Returns
- EV #E by 2 list of edge vertex indices
- FE #F by 3 list of face-edge relations (FE(f,c) is an edge incident on corner c of face f)
- EF #E by 2 list of edge-face relations (EF(e,:) are the two adjacent faces)
edges¶
Construct a list of unique edges from a given face matrix.
Parameters
F— #F by (3|4) matrix of mesh face indices
Returns
- #E by 2 matrix of unique edges
Construct a list of unique edges from a given list of polygon corner indices.
Parameters
I— Vectorized list of polygon corner indicesC— #polygons+1 list of cumulative polygon sizes
Returns
- #E by 2 matrix of unique edges
Construct a list of unique edges from a given adjacency matrix.
Parameters
A— #V by #V symmetric adjacency matrix
Returns
- #E by 2 matrix of unique edges
edges_to_path¶
Given undirected edges forming a single chain/loop, find the path visiting all nodes.
Parameters
E— #E by 2 list of undirected edges
Returns
- I #E+1 list of node indices tracing the chain (if loop: I[0]==I[-1])
- J #E list of indices into E tracing I
- K #E list of column indices in E (0 or 1) indicating edge direction
euler_characteristic¶
Compute the Euler characteristic of a mesh: χ = |V| - |E| + |F|
Parameters
F— #F by dim list of mesh faces
Returns
- Euler characteristic (e.g. 2 for a closed genus-0 surface)
exact_geodesic¶
exact_geodesic(V: float64[m, n], F: int64[m, n], VS: int64[m] = Ellipsis, FS: int64[m] = Ellipsis, VT: int64[m] = Ellipsis, FT: int64[m] = Ellipsis) -> float64[m]
Exact geodesic algorithm for computing distances on a triangular mesh.
Parameters
V— #V by 3 matrix of vertex positionsF— #F by 3 matrix of face indicesVS— #VS by 1 vector of source vertex indicesFS— #FS by 1 vector of source face indicesVT— #VT by 1 vector of target vertex indicesFT— #FT by 1 vector of target face indicesD— #VT+#FT vector of geodesic distances from each target to the nearest source
exterior_edges¶
Determine boundary edges (edges with odd number of occurrences).
Parameters
F— #F by simplex_size list of faces
Returns
- E #E by simplex_size-1 list of exterior edges
extract_manifold_patches¶
Extract maximal manifold patches from a triangle mesh.
A patch is a maximal subset of faces connected via manifold edges.
Parameters
F— #F by 3 list of triangle indices
Returns
- n number of manifold patches
- P #F list of patch indices for each face
face_areas¶
Constructs a list of face areas of faces opposite each index in a tet list
Parameters
V— #V by 3 list of mesh vertex positionsT— #T by 3 list of tet mesh indices into VA— #T by 4 list of face areas corresponding to faces opposite vertices 0,1,2,3
face_occurrences¶
Count the occurrences of each face (row) in a list of face indices.
Parameters
F— #F by simplex_size list of faces
Returns
- C #F list of occurrence counts
facet_adjacency_matrix¶
Construct a #F×#F adjacency matrix with A(i,j)>0 indicating that faces i and j share an edge.
Parameters
F— #F by 3 list of facetsA— #F by #F adjacency matrix
facet_components¶
Compute connected components of facets based on edge-edge adjacency.
For connected components on vertices see igl::vertex_components
Parameters
F— #F by 3 list of triangle indicesC— #F list of connected component ids
Returns
- number of connected components
false_barycentric_subdivision¶
false_barycentric_subdivision(V: float64[m, n], F: int64[m, n]) -> tuple[float64[m, n], int64[m, n]]
Refine the mesh by adding the barycenter of each face
Parameters
V— #V by 3 coordinates of the verticesF— #F by 3 list of mesh faces (must be triangles)VD— #V + #F by 3 coordinate of the vertices of the dual mesh The added vertices are added at the end of VD (should not be same references as (V,F)FD— #F*3 by 3 faces of the dual mesh
fast_winding_number¶
Compute approximate winding number for each query point based on a triangle soup mesh.
Parameters
V— #V by 3 matrix of mesh vertex positionsF— #F by 3 matrix of triangle indicesQ— #Q by 3 matrix of query positions
Returns
- W #Q vector of winding number values for each query point
find_cross_field_singularities¶
find_cross_field_singularities(V: float64[m, n], F: int64[m, n], mismatch: int64[m, n]) -> tuple[int64[m], int64[m]]
Computes singularities of a cross field, assumed combed
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 3 eigen Matrix of face (quad) indicesmismatch— #F by 3 eigen Matrix containing the integer mismatch of the cross field across all face edgesisSingularity— #V by 1 boolean eigen Vector indicating the presence of a singularity on a vertexsingularityIndex— #V by 1 integer eigen Vector containing the singularity indices
find_cross_field_singularities(V: float64[m, n], F: int64[m, n], PD1: float64[m, n], PD2: float64[m, n], isCombed: bool = False) -> tuple[int64[m], int64[m]]
Wrapper that calculates the mismatch if it is not provided.
Parameters
PD1— #F by 3 eigen Matrix of the first per face cross field vectorPD2— #F by 3 eigen Matrix of the second per face cross field vectorisCombed— boolean indicating whether the cross field is combed \note the field in PD1 and PD2 MUST BE combed (see igl::comb_cross_field).
fit_cubic_bezier¶
Fit a G1-continuous cubic Bézier spline to an ordered list of points.
According to "An algorithm for automatically fitting digitized curves" [Schneider 1990].
Parameters
d— #d by dim list of points along a curve (roughly uniformly spaced). If d[0]==d[-1] the curve is treated as closed.error— maximum squared distance allowed
Returns
- cubics list of 4 by dim arrays of cubic Bézier control points
fit_plane¶
Fit a plane to a point cloud.
Parameters
V— #V by 3 matrix of 3D point cloud positions
Returns
- N 3-vector normal of the fitted plane
- C 3-vector of a point that lies on the fitted plane
flipped_triangles¶
Find indices of flipped triangles in a 2D UV mapping.
Parameters
V— #V by 2 list of UV vertex positionsF— #F by 3 list of triangle indices
Returns
- X list of indices into F of flipped triangles
flood_fill¶
Fill NaN values in a 3D grid via flood fill from non-NaN data.
Parameters
res— 3-vector of grid dimensions [nx, ny, nz]S— res(0)res(1)res(2) list of scalar values with NaNs to fill
Returns
- S same array with NaNs filled
gaussian_curvature¶
Compute discrete Gaussian curvature at each vertex of a 3D mesh.
Parameters
V— #V by 3 matrix of vertex positionsF— #F by 3 matrix of face indices
Returns
- K #V vector of discrete Gaussian curvature values at each vertex
grad¶
Compute the gradient operator on a triangle mesh.
Parameters
V— #V by 3 list of mesh vertex positionsF— #F by 3 (or #F by 4 for tetrahedrons) list of mesh face indicesG— #F*dim by #V Gradient operatoruniform— boolean indicating whether to use a uniform mesh instead of the vertices V
Returns
- Sparse gradient operator matrix G
grid¶
Construct vertices of a regular grid.
Parameters
res— Vector containing the number of vertices along each dimension
Returns
- GV Matrix containing grid vertex positions suitable for input to igl::marching_cubes.
harmonic¶
Compute k-harmonic weight functions "coordinates".
Parameters
V— #V by dim vertex positionsF— #F by simplex-size list of element indicesb— #b boundary indices into Vbc— #b by #W list of boundary valuesk— power of harmonic operation (1: harmonic, 2: biharmonic, etc)
Returns
- W #V by #W list of weights
harmonic_integrated_from_laplacian_and_mass¶
harmonic_integrated_from_laplacian_and_mass(L: scipy.sparse.csc_matrix[float], M: scipy.sparse.csc_matrix[float], k: int) -> scipy.sparse.csc_matrix[float]
Build the discrete k-harmonic operator (computing integrated quantities). That is, if the k-harmonic PDE is Q x = 0, then this minimizes x' Q x.
Parameters
L— #V by #V discrete (integrated) LaplacianM— #V by #V mass matrixk— power of harmonic operation (1: harmonic, 2: biharmonic, etc)
Returns
- Q #V by #V discrete (integrated) k-Laplacian
hausdorff¶
Compute the Hausdorff distance between two meshes.
d(A,B) = max( max min d(a,b) , max min d(b,a) ) a∈A b∈B b∈B a∈A
Parameters
VA— #VA by 3 list of vertex positions of mesh AFA— #FA by 3 list of face indices into VAVB— #VB by 3 list of vertex positions of mesh BFB— #FB by 3 list of face indices into VB
Returns
- d Hausdorff distance
heat_geodesics_precompute¶
heat_geodesics_precompute(V: float64[m, n], F: int64[m, n], t: float, data: HeatGeodesicsData) -> None
Precompute factorized solvers for computing a fast approximation of geodesic distances on a mesh (V,F). [Crane et al. 2013]
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh face indices into Vt— "heat" parameter (smaller --> more accurate, less stable)data— precomputation data (see heat_geodesics_solve)
Precompute factorized solvers for computing a fast approximation of geodesic distances on a mesh (V,F). [Crane et al. 2013]
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh face indices into Vdata— precomputation data (see heat_geodesics_solve)
heat_geodesics_solve¶
Compute fast approximate geodesic distances using precomputed data from a set of selected source vertices (gamma).
Parameters
data— precomputation data (see heat_geodesics_precompute)gamma— #gamma list of indices into V of source verticesD— #V list of distances to gamma \fileinfo
hessian¶
Constructs the finite element Hessian matrix as described in https://arxiv.org/abs/1707.04348, Natural Boundary Conditions for Smoothing in Geometry Processing (Oded Stein, Eitan Grinspun, Max Wardetzky, Alec Jacobson) The interior vertices are NOT set to zero yet.
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh elements (must be triangles)H— dim²⋅#V by #V Hessian matrix, each column i corresponding to V(i,:
hessian_energy¶
Constructs the Hessian energy matrix using mixed FEM as described in https://arxiv.org/abs/1707.04348 Natural Boundary Conditions for Smoothing in Geometry Processing (Oded Stein, Eitan Grinspun, Max Wardetzky, Alec Jacobson)
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh elements (must be triangles)Q— #V by #V Hessian energy matrix, each row/column i corresponding to V(i,:
hsv_to_rgb¶
Convert HSV colors to RGB.
Parameters
H— #H by 3 list of HSV values: h in [0,360], s in [0,1], v in [0,1]
Returns
- R #H by 3 list of RGB values in [0,1]
icosahedron¶
Construct a icosahedron with radius 1 centered at the origin
Outputs: V #V by 3 list of vertex positions F #F by 3 list of triangle indices into rows of V
in_element¶
Determine whether each point in a list of points is in the elements of a mesh.
@tparam DIM dimension of vertices in V (# of columns)
Parameters
V— #V by dim list of mesh vertex positions.Ele— #Ele by dim+1 list of mesh indices into #V.Q— #Q by dim list of query point positionsaabb— axis-aligned bounding box tree object (see AABB.h)I— #Q list of indices into Ele of first containing element (-1 means no containing element)
inradius¶
Compute the inradius of each triangle in a mesh (V,F)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of triangle indices into VR— #F list of inradii
internal_angles¶
Compute internal angles for all tets of a given tet mesh (V,T).
Parameters
V— #V by dim eigen Matrix of mesh vertex nD positionsF— #F by poly-size eigen Matrix of face (triangle) indicesK— #F by poly-size eigen Matrix of internal angles for triangles, columns correspond to edges [1,2],[2,0],[0,1]
intrinsic_delaunay_cotmatrix¶
intrinsic_delaunay_cotmatrix(V: float64[m, n], F: int64[m, n]) -> tuple[scipy.sparse.csc_matrix[float], float64[m, n], int64[m, n]]
Computes the discrete cotangent Laplacian of a mesh after converting it into its intrinsic Delaunay triangulation (see, e.g., [Fisher et al. 2007].
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh elements (triangles or tetrahedra)L— #V by #V cotangent matrix, each row i corresponding to V(i,:)l_intrinsic— #F by 3 list of intrinsic edge-lengths used to compute LF_intrinsic— #F by 3 list of intrinsic face indices used to compute L
intrinsic_delaunay_triangulation¶
intrinsic_delaunay_triangulation(l: float64[m, n], F: int64[m, n]) -> tuple[float64[m, n], int64[m, n], int64[m, n], int64[m, n], int64[m], list[list[int]]]
INTRINSIC_DELAUNAY_TRIANGULATION Flip edges intrinsically until all are "intrinsic Delaunay". See "An algorithm for the construction of intrinsic delaunay triangulations with applications to digital geometry processing" [Fisher et al. 2007].
Parameters
l_in— #F_in by 3 list of edge lengths (see edge_lengths)F_in— #F_in by 3 list of face indices into some unspecified vertex list Vl— #F by 3 list of edge lengthsF— #F by 3 list of new face indices. Note: Combinatorially F may contain non-manifold edges, duplicate faces and self-loops (e.g., an edge [1,1] or a face [1,1,1]). However, the intrinsic geometry is still well-defined and correct. See [Fisher et al. 2007] Figure 3 and 2nd to last paragraph of 1st page. Since F may be "non-eddge-manifold" in the usual combinatorial sense, it may be useful to call the more verbose overload below if disentangling edges will be necessary later on. Calling unique_edge_map on this F will give a different result than those outputs.E— #F3 by 2 list of all directed edges, such that E.row(f+#Fc) is theedge— opposite F(f,c)uE— #uE by 2 list of unique undirected edgesEMAP— #F*3 list of indices into uE, mapping each directed edge to uniqueundirected— edgeuE2E— #uE list of lists of indices into E of coexisting edges
is_border_vertex¶
Determine vertices on the open boundary of a manifold mesh with triangle faces.
Parameters
F— #F by 3 list of triangle indices
Returns
- #V vector of bools indicating if vertices are on the boundary
is_boundary_edge¶
Determine for each edge in E if it is a boundary edge in F.
Parameters
E— #E by 2 list of edges to queryF— #F by 3 list of triangles
Returns
- B #E list of bools, true iff edge is a boundary edge
Determine boundary edges of mesh F.
Parameters
F— #F by 3 list of triangles
Returns
- B #uE list of bools, true iff unique edge is boundary
- E #uE by 2 list of unique edges
- EMAP #F*3 list of indices into E
is_delaunay¶
Determine if each edge in a mesh is locally Delaunay.
Parameters
V— #V by dim list of vertex positionsF— #F by 3 list of triangle indices
Returns
- D #F by 3 bool array; D(f,e) is true iff edge e of face f is locally Delaunay. Boundary edges are Delaunay by definition.
is_edge_manifold¶
Check if the mesh is edge-manifold (every edge is incident to one or two oppositely oriented faces).
Parameters
F— #F by 3 list of triangle indicesBF— (if return_BF=True) #F by 3 list of flags for non-manifold edges opposite each vertexE— (if return_E=True) #E by 2 list of unique edgesEMAP— (if return_EMAP=True) 3*#F list of indices of opposite edges in EBE— (if return_BE=True) #E list of flags for whether each edge is non-manifold
Returns
- True if all edges are manifold, otherwise False
is_intrinsic_delaunay¶
Determine if each edge in the mesh (V,F) is Delaunay.
Parameters
l— #l by dim list of edge lengthsF— #F by 3 list of triangles indicesD— D #F by 3 list of bools revealing whether edges corresponding 23 31 12 are locally Delaunay. Boundary edges are by definition Delaunay. Non-Manifold edges are by definition not Delaunay.
is_irregular_vertex¶
Determine if each vertex is irregular (valence > 6 for triangles, > 4 for quads). Boundary vertices are ignored.
Parameters
F— #F by 3[4] list of triangle[quad] indices
Returns
- #V vector of bools, true if vertex is irregular
is_vertex_manifold¶
Check if a mesh is vertex-manifold.
This only checks whether the faces incident on each vertex form exactly one connected component. Vertices incident on non-manifold edges are not consider non-manifold by this function (see is_edge_manifold). Unreferenced verties are considered non-manifold (zero components).
Parameters
F— #F by 3 list of triangle indices
Returns
- B #V list indicate whether each vertex is locally manifold (the mesh is vertex manifold if all(B) == True
ismember_rows¶
Determine if row of A exist in rows of B
Parameters
A— ma by na matrix of IntegersB— mb by nb matrix of IntegersIA— ma by 1 lest of flags whether corresponding element of A exists in BLOCB— ma by 1 list matrix of indices in B locating matching element (-1 if not found), indices assume column major ordering
isolines¶
isolines(V: float64[m, n], F: int64[m, n], S: float64[m], vals: float64[m]) -> tuple[float64[m, n], int64[m, n], int64[m]]
Compute isolines of a scalar field on a triangle mesh.
Isolines may cross perfectly at vertices. The output should not contain degenerate segments (so long as the input does not contain degenerate faces). The output segments are oriented so that isolines curl counter-clockwise around local maxima (i.e., for 2D scalar fields). Unless an isoline hits a boundary, it should be a closed loop. Isolines may run perfectly along boundaries. Isolines should appear just "above" constants regions.
Parameters
V— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh triangle indices into VS— #S by 1 list of per-vertex scalar valuesvals— #vals by 1 list of values to compute isolines foriV— #iV by dim list of isoline vertex positionsiE— #iE by 2 list of edge indices into iVI— #iE by 1 list of indices into vals indicating which value each segment belongs to
isolines_intrinsic¶
isolines_intrinsic(F: int64[m, n], S: float64[m], vals: float64[m]) -> tuple[float64[m, n], int64[m], int64[m, n], int64[m]]
Compute isolines of a scalar field on a triangle mesh intrinsically.
See isolines.h for details.
Parameters
F— #F by 3 list of mesh triangle indices into some VS— #S by 1 list of per-vertex scalar valuesvals— #vals by 1 list of values to compute isolines foriB— #iB by 3 list of barycentric coordinates so that iV.row(i) = iB(i,0)V.row(F(iFI(i,0)) + iB(i,1)V.row(F(iFI(i,1)) + iB(i,2)*V.row(F(iFI(i,2))iF— #iB list of triangle indices for each row of iB (all points will either lie on an edge or vertex: an arbitrary incident face will be given).iE— #iE by 2 list of edge indices into iBI— #iE by 1 list of indices into vals indicating which value each segment belongs to
isolines_intrinsic(F: int64[m, n], S: float64[m], val: float, uE: int64[m, n], EMAP: int64[m], uEC: int64[m], uEE: int64[m]) -> tuple[float64[m, n], int64[m], int64[m, n]]
Compute isolines of a scalar field on a triangle mesh intrinsically.
See isolines.h for details.
Parameters
F— #F by 3 list of mesh triangle indices into some VS— #S by 1 list of per-vertex scalar valuesval— scalar value to compute isoline atuE— #uE by 2 list of unique undirected edgesEMAP— #F3 list of indices into uE, mapping each directed edge to unique undirected edge so that uE(EMAP(f+#Fc)) is the unique edge corresponding to E.row(f+#F*c)uEC— #uE+1 list of cumulative counts of directed edges sharing each unique edge so the uEC(i+1)-uEC(i) is the number of directed edges sharing the ith unique edge.uEE— #E list of indices into E, so that the consecutive segment of indices uEE.segment(uEC(i),uEC(i+1)-uEC(i)) lists all directed edges sharing the ith unique edge.iB— #iB by 3 list of barycentric coordinates so that iV.row(i) = iB(i,0)V.row(F(iFI(i,0)) + iB(i,1)V.row(F(iFI(i,1)) + iB(i,2)*V.row(F(iFI(i,2))iF— #iB list of triangle indices for each row of iB (all points will either lie on an edge or vertex: an arbitrary incident face will be given).iE— #iE by 2 list of edge indices into iB
iterative_closest_point¶
iterative_closest_point(VX: float64[m, n], FX: int64[m, n], VY: float64[m, n], FY: int64[m, n], num_samples: int = 100, max_iters: int = 100) -> tuple[float64[m, n], float64[m, n]]
Find rigid transformation placing mesh X onto mesh Y via ICP.
Minimizes: ∫_X inf_y∈Y ‖x*R+t - y‖² dx
Parameters
VX— #VX by 3 mesh X vertex positionsFX— #FX by 3 mesh X triangle indicesVY— #VY by 3 mesh Y vertex positionsFY— #FY by 3 mesh Y triangle indicesnum_samples— number of random samples per iterationmax_iters— maximum iterations
Returns
- R 3 by 3 rotation matrix
- t 1 by 3 translation vector
kelvinlets¶
kelvinlets(V: float64[m, n], x0: float64[m], f: float64[m], F: float64[m, n], epsilon: float = 1.0, falloff: float = 1.0, brushType: BrushType = BrushType.GRAB) -> float64[m, n]
Implements Pixar's Regularized Kelvinlets (Pixar Technical Memo #17-03): Sculpting Brushes based on Fundamental Solutions of Elasticity, a technique for real-time physically based volume sculpting of virtual elastic materials
Parameters
V— #V by dim list of input points in spacex0— dim-vector of brush tipf— dim-vector of brush force (translation)F— dim by dim matrix of brush force matrix (linear)params— parameters for the kelvinlet brush like brush radius, scale etcX— #V by dim list of output points in space
knn¶
knn(P: float64[m, n], V: float64[m, n], k: int, point_indices: Sequence[Sequence[int]], CH: int64[m, n], CN: float64[m, n], W: float64[m]) -> int64[m, n]
Given a 3D set of points P, an whole number k, and an octree find the indicies of the k nearest neighbors for each point in P. Note that each point is its own neighbor.
The octree data structures used in this function are intended to be the same ones output from igl::octree
Parameters
P— #P by 3 list of point locationsV— #V by 3 list of point locations for which may be neighborsk— number of neighbors to findpoint_indices— a vector of vectors, where the ith entry is a vector of the indices into P that are the ith octree cell's pointsCH— #OctreeCells by 8, where the ith row is the indices of the ith octree cell's childrenCN— #OctreeCells by 3, where the ith row is a 3d row vector representing the position of the ith cell's centerW— #OctreeCells, a vector where the ith entry is the width of the ith octree cellI— #P by k list of k-nearest-neighbor indices into V
lbs_matrix¶
Construct the linear blend skinning matrix M.
V' = M * T where V' are deformed positions, M encodes rest positions and weights, T is a stack of transposed transformation matrices.
Parameters
V— #V by dim list of rest vertex positionsW— #V by #handles list of skinning weights
Returns
- M #V by #handles*(dim+1) linear blend skinning matrix
lexicographic_triangulation¶
Compute a lexicographic triangulation of a 2D point set.
Uses a floating-point cross-product orientation predicate; may be inaccurate for nearly-collinear inputs.
Parameters
P— #P by 2 list of 2D vertex positionsF— #F by 3 list of face indices into P
lipschitz_octree¶
lipschitz_octree(origin: float64[m], h0: float, max_depth: int, udf: Callable[[Annotated[ArrayLike, dict(dtype='float64', shape=(None, 3), writable=False)]], float64[m]]) -> int64[m, n]
Given a minimum corner position (origin) and a side length (h0) and a maximum depth (max_depth), determine the possible active leaf octree cells based on an one-Lipschitz non-negative function to a level set (e.g., "unsigned distance function").
Parameters
origin— 3-vector of root cell origin (minimum corner)h0— side length of root cellmax_depth— maximum depth of octree (root is depth=0)udf— 1-Lipschitz function of (unsigned) distance to level set to a list of batched query pointsijk— #ijk by 3 list of octree leaf cell minimum corner subscripts
local_basis¶
Compute a local orthogonal reference system for each triangle in the given mesh.
Parameters
V— #V by 3 eigen matrix of vertex positionsF— #F by 3 list of mesh faces (must be triangles)B1— #F by 3 matrix of tangent vectors for each triangleB2— #F by 3 matrix of tangent vectors perpendicular to B1 for each triangleB3— #F by 3 matrix of normal vectors for each triangle
look_at¶
Compute a view matrix like gluLookAt.
Parameters
eye— 3-vector eye positioncenter— 3-vector center/target positionup— 3-vector up direction
Returns
- R 4x4 view (rotation+translation) matrix
loop¶
loop(V: float64[m, n], F: int64[m, n], number_of_subdivs: int = 1) -> tuple[float64[m, n], int64[m, n]]
Subdivide a mesh without moving vertices using loop subdivision. Returns new vertices and faces.
Parameters
V— #V by dim matrix of mesh verticesF— #F by 3 matrix of triangle facesnumber_of_subdivs— Number of subdivisions (default is 1)
Returns
- A tuple containing: - NV: New vertex positions with original vertices at the top - NF: Matrix of new face indices
loop_matrix¶
Subdivide a mesh without moving vertices. Returns the subdivision matrix and new faces.
Parameters
n_verts— Number of mesh verticesF— #F by 3 matrix of triangle faces
Returns
- A tuple containing: - S: Sparse subdivision matrix - NF: Matrix of new faces
lscm¶
lscm(V: float64[m, n], F: int64[m, n], b: int64[m], bc: float64[m, n]) -> tuple[float64[m, n], scipy.sparse.csc_matrix[float]]
Compute a Least-squares conformal map parametrization.
Parameters
V— #V by 3 list of mesh vertex positionsF— #F by 3 list of mesh faces (must be triangles)b— #b list of boundary indices into Vbc— #b by 2 list of boundary valuesV_uv— #V by 2 list of 2D mesh vertex positions in UV spaceQ— #Vx2 by #Vx2 symmetric positive semi-definite matrix for computing LSCM energy
Returns
- Tuple containing: - V_uv: UV coordinates of vertices - Q: Symmetric positive semi-definite matrix for LSCM energy
map_vertices_to_circle¶
Map the vertices whose indices are in a given boundary loop (bnd) on the unit circle with spacing proportional to the original boundary edge lengths.
Parameters
V— #V by dim list of mesh vertex positionsb— #W list of vertex idsUV— #W by 2 list of 2D position on the unit circle for the vertices in b
marching_cubes¶
marching_cubes(S: float64[m], GV: float64[m, n], nx: int, ny: int, nz: int, isovalue: float = 0) -> tuple[float64[m, n], int64[m, n], dict[int, int]]
Performs marching cubes reconstruction on a grid defined by values, and points, and generates a mesh defined by vertices and faces
Parameters
S— nxnynz list of values at each grid corner i.e. S(x + yxres + zxres*yres) for corner (x,y,z)GV— nxnynz by 3 array of corresponding grid corner vertex locationsnx— resolutions of the grid in x dimensionny— resolutions of the grid in y dimensionnz— resolutions of the grid in z dimensionisovalue— the isovalue of the surface to reconstructV— #V by 3 list of mesh vertex positionsF— #F by 3 list of mesh triangle indices into rows of VE2V— map from edge key to index into rows of V # unpack keys into (i,j,v) index triplets EV = np.array([[k & 0xFFFFFFFF, k >> 32, v] for k, v in E2V.items()], dtype=np.int64)
marching_cubes(S: float64[m], GV: float64[m, n], GI: int64[m, n], isovalue: float = 0.0) -> tuple[float64[m, n], int64[m, n]]
Performs marching cubes reconstruction on a grid defined by values, and points, and generates a mesh defined by vertices and faces
Parameters
S— #S list of scalar field valuesGV— #S by 3 list of referenced grid vertex positionsGI— #GI by 8 list of grid corner indices into rows of GVisovalue— the isovalue of the surface to reconstructV— #V by 3 list of mesh vertex positionsF— #F by 3 list of mesh triangle indices into rows of V
massmatrix¶
massmatrix(V: float64[m, n], F: int64[m, n], type: MassMatrixType = MassMatrixType.MASSMATRIX_TYPE_DEFAULT) -> scipy.sparse.csc_matrix[float]
Constructs the mass (area) matrix for a given mesh (V,F).
@tparam DerivedV derived type of eigen matrix for V (e.g. derived from MatrixXd) @tparam DerivedF derived type of eigen matrix for F (e.g. derived from MatrixXi) @tparam Scalar scalar type for eigen sparse matrix (e.g. double)
Parameters
V— #V by dim list of mesh vertex positionsF— #F by simplex_size list of mesh elements (triangles or tetrahedra)type— one of the following ints: MASSMATRIX_TYPE_BARYCENTRIC barycentric {default for tetrahedra} MASSMATRIX_TYPE_VORONOI voronoi-hybrid {default for triangles} MASSMATRIX_TYPE_FULL fullM— #V by #V mass matrix
massmatrix_intrinsic¶
massmatrix_intrinsic(l: float64[m, n], F: int64[m, n], type: MassMatrixType = MassMatrixType.MASSMATRIX_TYPE_DEFAULT) -> scipy.sparse.csc_matrix[float]
Constructs the mass matrix for a given mesh with faces F and edge lengths l.
Parameters
l— #F by 3 list of (half-)edge lengthsF— #F by 3 list of face indices into some (not necessarily determined/embedable) list of vertex positions V. It is assumed #V == F.maxCoeff()+1L— #V by #V sparse Laplacian matrix
matlab_format¶
Format a dense matrix for MATLAB-style output.
Format a sparse matrix for MATLAB-style output in IJV format.
Format a double scalar for MATLAB-style output.
matlab_format_index¶
Format a matrix for MATLAB-style output with 1-based indexing.
min_quad_with_fixed¶
min_quad_with_fixed(A: scipy.sparse.csc_matrix[float] = Ellipsis, B: float64[m, n] = Ellipsis, known: int64[m] = Ellipsis, Y: float64[m, n] = Ellipsis, Aeq: scipy.sparse.csc_matrix[float] = Ellipsis, Beq: float64[m, n] = Ellipsis, pd: bool = True) -> float64[m, n]
Minimize a convex quadratic energy subject to fixed values and linear equality constraints.
The function minimizes trace(0.5 * Z' * A * Z + Z' * B) subject to: Z(known,:) = Y, and Aeq * Z = Beq
Parameters
A— n by n matrix of quadratic coefficientsB— n by k matrix of linear coefficientsknown— list of indices to known rows in ZY— n by k matrix of fixed values corresponding to known rows in ZAeq— m by n matrix of linear equality constraint coefficientsBeq— m by k matrix of linear equality constraint target valuespd— flag specifying whether A(unknown,unknown) is positive definiteZ— solution matrix that minimizes the objective under constraints
Returns
- Z solution matrix
min_quad_with_fixed_precompute¶
min_quad_with_fixed_precompute(A: scipy.sparse.csc_matrix[float] = Ellipsis, known: int64[m] = Ellipsis, Aeq: scipy.sparse.csc_matrix[float] = Ellipsis, pd: bool = True, data: min_quad_with_fixed_data = Ellipsis) -> None
Precompute convex quadratic optimization problem.
min_quad_with_fixed_solve¶
min_quad_with_fixed_solve(data: min_quad_with_fixed_data, B: float64[m, n] = Ellipsis, Y: float64[m, n] = Ellipsis, Beq: float64[m, n] = Ellipsis) -> float64[m, n]
Solve the precomputed convex quadratic optimization problem.
moments¶
Computes the moments of mass for a solid object bound by a triangle mesh.
Parameters
V— #V by 3 list of rest domain positionsF— #F by 3 list of triangle indices into Vm0— zeroth moment of mass, total signed volume of solid.m1— first moment of mass, center of mass (centroid) times total massm2— second moment of mass, moment of inertia with center of mass as reference point
mvc¶
Compute mean value coordinates for a polygon.
Parameters
V— #V by dim list of query point positions (dim=2 or 3)C— #C by dim list of polygon vertex positions in CCW order
Returns
- W #V by #C matrix of mean value coordinate weights
noop¶
noop(N: float64[m, n] = Ellipsis, I: int64[m, n] = Ellipsis, SN: scipy.sparse.csc_matrix[float] = Ellipsis, SI: scipy.sparse.csc_matrix[int] = Ellipsis) -> object
Dummy function that does nothing. Useful for timing bindings overhead.
octree¶
Given a set of 3D points P, generate data structures for a pointerless octree. Each cell stores its points, children, center location and width. Our octree is not dense. We use the following rule: if the current cell has any number of points, it will have all 8 children. A leaf cell will have -1's as its list of child indices.
We use a binary numbering of children. Treating the parent cell's center as the origin, we number the octants in the following manner: The first bit is 1 iff the octant's x coordinate is positive The second bit is 1 iff the octant's y coordinate is positive The third bit is 1 iff the octant's z coordinate is positive
For example, the octant with negative x, positive y, positive z is: 110 binary = 6 decimal
Parameters
P— #P by 3 list of point locationspoint_indices— a vector of vectors, where the ith entry is a vector of the indices into P that are the ith octree cell's pointsCH— #OctreeCells by 8, where the ith row is the indices of the ith octree cell's childrenCN— #OctreeCells by 3, where the ith row is a 3d row vector representing the position of the ith cell's centerW— #OctreeCells, a vector where the ith entry is the width of the ith octree cell
offset_surface¶
offset_surface(V: float64[m, n], F: int64[m, n], isolevel: float, s: int, signed_distance_type: SignedDistanceType) -> tuple[float64[m, n], int64[m, n], float64[m, n], int64[m], float64[m, n]]
Compute a triangulated offset surface using matching cubes on a grid of signed distance values from the input triangle mesh.
Parameters
V— #V by 3 list of mesh vertex positionsF— #F by 3 list of mesh triangle indices into Visolevel— iso level to extract (signed distance: negative inside)s— number of grid cells along longest side (controls resolution)signed_distance_type— type of signing to use one of SIGNED_DISTANCE_TYPE_PSEUDONORMAL, SIGNED_DISTANCE_TYPE_WINDING_NUMBER, SIGNED_DISTANCE_TYPE_DEFAULT, SIGNED_DISTANCE_TYPE_UNSIGNED, SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER
Returns
- Tuple containing: - SV: #SV by 3 list of output surface mesh vertex positions - SF: #SF by 3 list of output mesh triangle indices into SV - GV: #GV=side(0)side(1)side(2) by 3 list of grid cell centers - side: list of number of grid cells in x, y, and z directions - so: #GV by 3 list of signed distance values near
isolevel('far' fromisolevelthese values are incorrect)
on_boundary¶
Determine boundary facets of mesh elements stored in T.
Parameters
T— m by 3|4 list of triangle or tetrahedron indices, where m is the number of elements
Returns
- Tuple containing: - I: m-length vector of bools indicating if each element is on the boundary - C: m by 3|4 matrix of bools indicating if each opposite facet is on the boundary
orient_halfedges¶
Orients halfedges for a triangle mesh, assigning them to a unique edge.
Parameters
F— #F by 3 input mesh connectivityE— #F by 3 a mapping from each halfedge to each edgeoE— #F by 3 the orientation (e.g., -1 or 1) of each halfedge compared to the orientation of the actual edge. Every edge appears positively oriented exactly once.
orient_outward¶
Orient each component of a mesh so normals point away from the centroid.
Parameters
V— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesC— #F list of component ids (from orientable_patches)
Returns
- FF #F by 3 list of reoriented triangle indices
- I max(C)+1 list of bools: true if face was flipped
orientable_patches¶
Compute connected components of facets connected by manifold edges.
Parameters
F— #F by simplex_size list of facets
Returns
- C #F list of component ids
Compute connected components of facets connected by manifold edges, also returns the adjacency matrix.
Parameters
F— #F by simplex_size list of facets
Returns
- C #F list of component ids
- A #F by #F sparse adjacency matrix
oriented_bounding_box¶
oriented_bounding_box(P: float64[m, n], n: int = 10000, minimize_type: OrientedBoundingBoxMinimizeType = OrientedBoundingBoxMinimizeType.ORIENTED_BOUNDING_BOX_MINIMIZE_VOLUME) -> float64[m, n]
Given a set of points compute the rotation transformation of them such that their axis-aligned bounding box is as small as possible.
Consider passing the points on the convex hull of original list of points.
Parameters
P— #P by 3 list of point locationsn— number of rotations to tryminimize_type— which quantity to minimizeR— rotation matrix
oriented_facets¶
Determines all directed facets of a given set of simplicial elements.
Parameters
F— #F by simplex_size matrix of simplices
Returns
- E #E by (simplex_size-1) matrix of directed facets, such that each row in E represents a facet opposite to a vertex in F
per_corner_normals¶
per_corner_normals(V: float64[m, n], F: int64[m, n], corner_threshold_degrees: float = 20.0) -> float64[m, n]
Compute per-corner normals by averaging incident face normals within a threshold angle.
Parameters
V— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicescorner_threshold_degrees— dihedral angle threshold in degrees; faces with normals deviating more than this are not averaged together
Returns
- CN #F3 by 3 list of corner normals; CN.row(3f+c) is the normal at corner c of face f
per_edge_normals¶
per_edge_normals(V: float64[m, n], F: int64[m, n], weight: PerEdgeNormalsWeightingType = PerEdgeNormalsWeightingType.PER_EDGE_NORMALS_WEIGHTING_TYPE_DEFAULT) -> tuple[float64[m, n], int64[m, n], int64[m]]
Compute per-edge normals for a triangle mesh.
Parameters
V— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesweight— weighting type (UNIFORM, AREA, or DEFAULT)
Returns
- N #E by 3 list of edge normals
- E #E by 2 list of edge vertex indices
- EMAP #F*3 list of indices from face-edges to E
per_face_normals¶
Compute face normals via vertex position list, face list
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsF— #F by 3 eigen Matrix of face (triangle) indicesZ— 3 vector normal given to faces with degenerate normal.N— #F by 3 eigen Matrix of mesh face (triangle) 3D normals
per_face_normals(V: float64[m, n], I: int64[m], C: int64[m]) -> tuple[float64[m, n], float64[m, n], int64[m, n], int64[m]]
Compute face normals via vertex position list, polygon stream
Parameters
V— #V by 3 eigen Matrix of mesh vertex 3D positionsI— #I vectorized list of polygon corner indices into rows of some matrix VC— #polygons+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of the ith polygonN— #F by 3 eigen Matrix of mesh face (triangle) 3D normalsVV— #I+#polygons by 3 list of auxiliary triangle mesh vertex positionsFF— #I by 3 list of triangle indices into rows of VVJ— #I list of indices into original polygons
per_vertex_attribute_smoothing¶
Smooth vertex attributes using uniform Laplacian averaging.
Parameters
Ain— #V by #A matrix of vertex attributesF— #F by 3 list of triangle indices
Returns
- Aout #V by #A smoothed vertex attributes
per_vertex_normals¶
per_vertex_normals(V: float64[m, n], F: int64[m, n], weighting: PerVertexNormalsWeightingType = PerVertexNormalsWeightingType.PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT) -> float64[m, n]
Compute per-vertex normals with optional weighting and face normals.
Parameters
V— #V by 3 matrix of vertex positionsF— #F by 3 matrix of face indicesweighting— Optional string for weighting type ("uniform", "area", "angle", or "default")
Returns
- N #V by 3 matrix of vertex normals
per_vertex_normals(V: float64[m, n], F: int64[m, n], weighting: PerVertexNormalsWeightingType = PerVertexNormalsWeightingType.PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT, FN: float64[m, n] = Ellipsis) -> float64[m, n]
Compute per-vertex normals with optional weighting and face normals.
Parameters
V— #V by 3 matrix of vertex positionsF— #F by 3 matrix of face indicesweighting— Optional string for weighting type ("uniform", "area", "angle", or "default")FN— Optional #F by 3 matrix of face normals
Returns
- N #V by 3 matrix of vertex normals
point_mesh_squared_distance¶
point_mesh_squared_distance(P: float64[m, n], V: float64[m, n], Ele: int64[m, n]) -> tuple[float64[m], int64[m], float64[m, n]]
Compute distances from a set of points P to a triangle mesh (V,F)
Parameters
P— #P by 3 list of query point positionsV— #V by 3 list of vertex positionsEle— #Ele by (3|2|1) list of (triangle|edge|point) indicessqrD— #P list of smallest squared distancesI— #P list of primitive indices corresponding to smallest distancesC— #P by 3 list of closest points \bug This only computes distances to given primitives. So unreferenced vertices are ignored. However, degenerate primitives are handled correctly: triangle [1 2 2] is treated as a segment [1 2], and triangle [1 1 1] is treated as a point. So one could add extra combinatorially degenerate rows to Ele for all unreferenced vertices to also get distances to points.
polar_dec¶
polar_dec(A: float64[m, n], include_reflections: bool = False) -> tuple[float64[m, n], float64[m, n]]
Compute polar decomposition A = R*T of a matrix.
Parameters
A— n by n matrix to decomposeinclude_reflections— if true, R may be a reflection (det=-1)
Returns
- R n by n orthogonal factor
- T n by n symmetric positive semi-definite stretch factor
polar_dec(A: float64[m, n], include_reflections: bool) -> tuple[float64[m, n], float64[m, n], float64[m, n], float64[m, n], float64[m, n]]
Compute polar decomposition A = R*T with full SVD.
Parameters
A— n by n matrix to decomposeinclude_reflections— if true, R may be a reflection (det=-1)
Returns
- R n by n orthogonal factor
- T n by n symmetric stretch factor
- U n by n left singular vectors
- S n vector of singular values
- V n by n right singular vectors
polar_svd¶
polar_svd(A: float64[m, n], include_reflections: bool = False) -> tuple[float64[m, n], float64[m, n], float64[m, n], float64[m], float64[m, n]]
Computes the polar decomposition of a NxN matrix A using SVD.
Parameters
A— NxN matrix to be decomposedincludeReflections— Whether to allow R to be a reflection (default is False)return_U— If true, include the left-singular vectors U in the output (default is False)return_S— If true, include the singular values S in the output (default is False)return_V— If true, include the right-singular vectors V in the output (default is False)
Returns
- Tuple containing (R,T) and selected outputs in the order specified by the flags
polygon_corners¶
Convert a list-of-lists polygon mesh faces representation to list of polygon corners and sizes
Parameters
P— #P list of lists of vertex indices into rows of some matrix VI— #I vectorized list of polygon corner indices into rows of some matrix VC— #P+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of the ith polygon
\brief Convert a pure k-gon list of polygon mesh indices to list of polygon corners and sizes
Parameters
Q— #Q by k list of polygon indices (ith row is a k-gon, unless Q(i,j) = -1 then it's a j-gon)I— #I vectorized list of polygon corner indices into rows of some matrix VC— #P+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of the ith polygon
polygons_to_triangles¶
Given a polygon mesh, trivially triangulate each polygon with a fan. This purely combinatorial triangulation will work well for convex/flat polygons and degrade otherwise.
Parameters
I— #I vectorized list of polygon corner indices into rows of some matrix VC— #polygons+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of the ith polygonF— #F by 3 list of triangle indices into rows of VJ— #F list of indices into 0:#P-1 of corresponding polygon
principal_curvature¶
principal_curvature(V: float64[m, n], F: int64[m, n], radius: int = 5, useKring: bool = True) -> tuple[float64[m, n], float64[m, n], float64[m], float64[m], list[int]]
Compute principal curvature directions and magnitudes for each vertex in a 3D mesh.
Parameters
V— #V by 3 matrix of vertex positionsF— #F by 3 matrix of face indices (triangular mesh)radius— controls the size of the neighborhood, where 1 corresponds to average edge lengthuseKring— boolean to use Kring neighborhood instead of ball neighborhood
Returns
- Tuple containing: - PD1: #V by 3 maximal curvature direction for each vertex - PD2: #V by 3 minimal curvature direction for each vertex - PV1: #V vector of maximal curvature values for each vertex - PV2: #V vector of minimal curvature values for each vertex - bad_vertices: list of indices of bad vertices, if any
procrustes¶
procrustes(X: float64[m, n], Y: float64[m, n], include_scaling: bool = False, include_reflections: bool = False) -> tuple[float, float64[m, n], float64[m]]
Solve the Procrustes problem: find s, R, t minimizing |sXR + t - Y|².
Parameters
X— #V by dim first list of pointsY— #V by dim second list of pointsinclude_scaling— if true, solve for scale sinclude_reflections— if true, R may be a reflection
Returns
- scale scalar scale factor s
- R dim by dim rotation (or reflection) matrix
- t dim translation vector
project¶
project(scene: float64[m, n], model: float64[m, n], proj: float64[m, n], viewport: float64[m]) -> float64[m, n]
Eigen reimplementation of gluUnproject for batch processing.
Parameters
scne— #P by 3 matrix of screen space x, y, and z coordinatesmodel— 4x4 model-view matrixproj— 4x4 projection matrixviewport— 4-long viewport vector
Returns
- win #P by 3 matrix of the projected x, y, and z coordinates
project_to_line¶
Project multiple points onto a line defined by points S and D.
Parameters
P— #P by dim list of points to be projectedS— 1 by dim starting position of lineD— 1 by dim ending position of line
Returns
- Tuple containing: - t: #P by 1 list of parameters along the line for each point - sqrD: #P by 1 list of squared distances from each point to the line
project_to_line_segment¶
project_to_line_segment(P: float64[m, n], S: float64[m], D: float64[m]) -> tuple[float64[m], float64[m]]
Project points onto a line segment defined by points S and D.
Parameters
P— #P by dim list of points to be projectedS— 1 by dim starting position of line segmentD— 1 by dim ending position of line segment
Returns
- Tuple containing: - t: #P by 1 list of parameters along the line segment for each point - sqrD: #P by 1 list of squared distances from each point to its projection
pseudonormal_test¶
pseudonormal_test(V: float64[m, n], F: int64[m, n], FN: float64[m, n], VN: float64[m, n], EN: float64[m, n], EMAP: int64[m, n], q: float64[m, n], c: float64[m, n], f: int) -> tuple[float, float64[m, n]]
Determine the sign of a query point w.r.t. a mesh using the pseudonormal.
Given a mesh (V,F), a query point q, a precomputed closest point c on face f, determine whether q is inside (s=-1) or outside (s=+1) the mesh.
Parameters
V— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesFN— #F by 3 list of face normalsVN— #V by 3 list of vertex normals (angle weighted)EN— #E by 3 list of edge normals (uniform weighted)EMAP— #F*3 mapping from face-edges to Eq— 3-vector query pointc— 3-vector closest point on mesh (precomputed)f— index of closest face in F
Returns
- s sign: -1 if inside, +1 if outside
- n 3-vector normal at closest point
qslim¶
qslim(V: float64[m, n], F: int32[m, n], max_m: int = 0, block_intersections: bool = False) -> tuple[float64[m, n], int64[m, n], int64[m], int64[m]]
Assumes (V,F) is a manifold mesh (possibly with boundary) collapses edges until desired number of faces is achieved. This uses default edge cost and merged vertex placement functions {edge length, edge midpoint}.
See \fileinfo for more details.
Parameters
V— #V by dim list of vertex positionsF— #F by 3 list of face indices into V.max_m— desired number of output facesblock_intersections— whether to block intersections (see intersection_blocking_collapse_edge_callbacks)U— #U by dim list of output vertex posistions (can be same ref as V)G— #G by 3 list of output face indices into U (can be same ref as G)J— #G list of indices into F of birth faceI— #U list of indices into V of birth vertices
Returns
- true if m was reached (otherwise #G > m)
quad_grid¶
Create a regular quad quad_grid of elements (only 2D supported, currently) Vertex
position order is compatible with igl::quad_grid
Parameters
nx— number of vertices in the x directionny— number of vertices in the y directionV— nx*ny by 2 list of vertex positionsQ— (nx-1)*(ny-1) by 4 list of quad indices into VE— (nx-1)ny+(ny-1)nx by 2 list of undirected quad edge indices into V
random_dir¶
Generate a uniformly random unit direction in 3D.
Returns
- 3-vector random unit direction
random_dir_stratified¶
Generate n stratified uniformly random unit directions in 3D.
Parameters
n— number of directions
Returns
- n by 3 matrix of random unit directions
random_points_on_mesh¶
random_points_on_mesh(n: int, V: float64[m, n], F: int64[m, n], seed: int | None = None) -> tuple[float64[m, n], int64[m], float64[m, n]]
Randomly sample a mesh (V,F) n times.
Parameters
n— number of samplesV— #V by dim list of mesh vertex positionsF— #F by 3 list of mesh triangle indicesB— n by 3 list of barycentric coordinates, ith row are coordinates of ith sampled point in face FI(i)urbg— An instance of UnformRandomBitGenerator (e.g.,std::minstd_rand(0))FI— n list of indices into Furbg— An instance of UnformRandomBitGenerator.X— n by dim list of sample positions.
ray_mesh_intersect¶
ray_mesh_intersect(source: float64[m], dir: float64[m], V: float64[m, n], F: int64[m, n], first: bool = False) -> list[tuple[int, float, float, float]]
Shoot a ray against a mesh (V, F) and collect hits.
Parameters
source— 3-vector origin of the raydir— 3-vector direction of the rayV— #V by 3 list of mesh vertex positionsF— #F by 3 list of mesh face indices into Vfirst— If True, only return the first hit (if any)
Returns
- Sorted list of hits if any exist, otherwise None
ray_sphere_intersect¶
ray_sphere_intersect(o: float64[m, n], d: float64[m, n], c: float64[m, n], r: float) -> tuple[int, float, float]
Compute intersection(s) between a ray and a sphere.
Parameters
o— 3-vector ray origind— 3-vector ray directionc— 3-vector sphere centerr— sphere radius
Returns
- n number of intersections (0, 1, or 2)
- t0 parameter of first hit: hit = o + t0*d
- t1 parameter of second hit
ray_triangle_intersect¶
ray_triangle_intersect(O: float64[m, n], D: float64[m, n], V0: float64[m, n], V1: float64[m, n], V2: float64[m, n], epsilon: float = 1e-10) -> tuple[bool, float, float, float, bool]
Determine whether a ray intersects a triangle.
Parameters
O— 3-vector ray originD— 3-vector ray directionV0— 3-vector first triangle vertexV1— 3-vector second triangle vertexV2— 3-vector third triangle vertexepsilon— tolerance for parallel check
Returns
- hit true if ray intersects triangle
- t distance along ray to intersection
- u barycentric coordinate of V1
- v barycentric coordinate of V2
- parallel true if ray is parallel to triangle
readCSV¶
Read a matrix from a CSV file.
Parameters
filename— path to .csv file
Returns
- M matrix of values read from the CSV
readDMAT¶
Read a matrix from a .dmat file.
Parameters
file_name— path to .dmat file
Returns
- Eigen matrix containing read-in coefficients
readMESH¶
Load a tetrahedral volume mesh from a .mesh file.
Parameters
mesh_file_name— Path of the .mesh file to read
Returns
- Tuple containing: - V: #V by 3 matrix of vertex positions - T: #T by 4 matrix of tetrahedral indices into vertices - F: #F by 3 matrix of face indices into vertices @throws std::runtime_error if file reading fails
readMSH¶
readMSH(msh_file_name: str | os.PathLike) -> tuple[float64[m, n], int64[m, n], int64[m, n], int64[m], int64[m], list[str], list[float64[m, n]], list[str], list[float64[m, n]], list[float64[m, n]]]
read triangle surface mesh and tetrahedral volume mesh from .msh file
Parameters
msh— - file nameX— eigen double matrix of vertex positions #X by 3Tri— #Tri eigen integer matrix of triangular faces indices into vertex positionsTet— #Tet eigen integer matrix of tetrahedral indices into vertex positionsTriTag— #Tri eigen integer vector of tags associated with surface facesTetTag— #Tet eigen integer vector of tags associated with volume elementsXFields— #XFields list of strings with field names associated with nodesXF— #XFields list of eigen double matrices, fields associated with nodesEFields— #EFields list of strings with field names associated with elementsTriF— #EFields list of eigen double matrices, fields associated with surface elementsTetF— #EFields list of eigen double matrices, fields associated with volume elements
Returns
- true on success \bug only version 2.2 of .msh file is supported (gmsh 3.X) \bug only triangle surface elements and tetrahedral volumetric elements are supported \bug only 3D information is supported \bug only the 1st tag per element is returned (physical) \bug same element fields are expected to be associated with surface elements and volumetric elements
readOBJ¶
readOBJ(filename: str | os.PathLike) -> tuple[float64[m, n], float64[m, n], float64[m, n], int64[m, n], int64[m, n], int64[m, n]]
Read a mesh from an ascii obj file, filling in vertex positions, normals and texture coordinates. Mesh may have faces of any number of degree
Parameters
str— path to .obj fileV— double matrix of vertex positions #V by 3TC— double matrix of texture coordinats #TC by 2N— double matrix of corner normals #N by 3F— #F list of face indices into vertex positionsFTC— #F list of face indices into vertex texture coordinatesFN— #F list of face indices into vertex normals
readOFF¶
Read mesh from an ascii .off file
Parameters
filename— path to fileV— double matrix #V by 3F— int matrix #F by 3N,C— double matrix #V by 3 normals or colors
Returns
- true iff success
readSTL¶
Read a mesh from an ASCII or binary STL file.
Note: STL files may have duplicate vertices. Use remove_duplicate_vertices to merge them.
Parameters
filename— path to .stl file
Returns
- V #F*3 by 3 list of vertex positions (one per triangle corner)
- F #F by 3 list of triangle indices into V
- N #F by 3 list of face normals
read_triangle_mesh¶
Read mesh from an ascii file with automatic detection of file format among: mesh, msh obj, off, ply, stl, wrl.
Parameters
filename— path to fileV— double matrix #V by 3F— int matrix #F by 3
Returns
- true iff success
remove_duplicate_vertices¶
remove_duplicate_vertices(V: float64[m, n], epsilon: float) -> tuple[float64[m, n], int64[m], int64[m]]
Remove duplicate vertices up to a uniqueness tolerance (epsilon).
Parameters
V— #V by dim list of vertex positionsepsilon— Uniqueness tolerance used coordinate-wise
Returns
- Tuple containing: - SV: #SV by dim new list of unique vertex positions - SVI: #SV list of indices so SV = V(SVI,:) - SVJ: #V list of indices so V = SV(SVJ,:)
remove_duplicate_vertices(V: float64[m, n], F: int64[m, n], epsilon: float) -> tuple[float64[m, n], int64[m], int64[m], int64[m, n]]
Remove duplicate vertices and remap faces to new indices.
Parameters
V— #V by dim list of vertex positionsF— #F by dim list of face indicesreturn_SVJ— If true, return the SVJ mapping indices
Returns
- Tuple containing: - SV: #SV by dim new list of unique vertex positions - SVI: #SV list of indices so SV = V(SVI,:) - SVJ: #V list of indices so V = SV(SVJ,:) - SF: #F by dim list of remapped face indices into SV
remove_unreferenced¶
remove_unreferenced(F: float64[m, n], n: int64[m, n] = 0) -> tuple[float64[m, n], int64[m, n], int64[m], int64[m]]
Remove unreferenced vertices from V, updating F accordingly
Parameters
V— #V by dim list of mesh vertex positionsF— #F by ss list of simplices (Values of -1 are quitely skipped)NV— #NV by dim list of simplicesNF— #NF by ss list of simplicesI— #V by 1 list of indices such that: NF = IM(F) and NT = IM(T) and V(find(IM<=size(NV,1)),:) = NVJ— #NV by 1 list, such that NV = V(J,:)
resolve_duplicated_faces¶
Resolve duplicated faces according to the following rules per unique face:
- If the number of positively oriented faces equals the number of negatively oriented faces, remove all duplicated faces at this triangle.
- If the number of positively oriented faces equals the number of negatively oriented faces plus 1, keep one of the positively oriented faces.
- If the number of positively oriented faces equals the number of negatively oriented faces minus 1, keep one of the negatively oriented faces.
- If the number of positively oriented faces differs from the number of negatively oriented faces by more than 1, the mesh is not orientable at that triangle and all of its copies are dropped.
Parameters
F1— #F1 by 3 array of input faces
Returns
- Tuple (F2, J) where F2 #F2 by 3 array of output faces without duplicated faces J #F2 list of indices into F1
rgb_to_hsv¶
Convert RGB colors to HSV.
Parameters
R— #R by 3 list of RGB values in [0,1]
Returns
- H #R by 3 list of HSV values: h in [0,360], s in [0,1], v in [0,1]
rigid_alignment¶
rigid_alignment(X: float64[m, n], P: float64[m, n], N: float64[m, n]) -> tuple[float64[m, n], float64[m, n]]
Find rigid transformation (R,t) minimizing ‖(X*R+t-P)'N‖².
Parameters
X— #X by 3 list of query pointsP— #X by 3 list of corresponding (closest) points on targetN— #X by 3 list of unit normals at each point in P
Returns
- R 3 by 3 rotation matrix
- t 1 by 3 translation vector
rotate_vectors¶
rotate_vectors(V: float64[m, n], A: float64[m], B1: float64[m, n], B2: float64[m, n]) -> float64[m, n]
Rotate the vectors V by A radians on the tangent plane spanned by B1 and B2
Parameters
V— #V by 3 eigen Matrix of vectorsA— #V eigen vector of rotation angles or a single angle to be applied to all vectorsB1— #V by 3 eigen Matrix of base vector 1B2— #V by 3 eigen Matrix of base vector 2
Returns
- the rotated vectors
rotation_matrix_from_directions¶
Compute the rotation matrix that rotates unit vector v0 to unit vector v1.
Parameters
v0— 3-vector source directionv1— 3-vector target direction
Returns
- 3 by 3 rotation matrix R such that R*v0 ≈ v1
sample_edges¶
Compute k extra sample points along each edge.
Parameters
V— #V by dim list of vertex positionsE— #E by 2 list of edge indices into Vk— number of extra samples per edge (not including endpoints)
Returns
- S sampled positions; begins with V so E still indexes into S
segment_segment_intersect¶
segment_segment_intersect(p: float64[m, n], r: float64[m, n], q: float64[m, n], s: float64[m, n], eps: float = 1e-06) -> tuple[bool, float, float]
Determine whether two 3D line segments intersect.
Segment A: p + tr, t in [0,1] Segment B: q + us, u in [0,1]
Parameters
p— 3-vector origin of segment Ar— 3-vector direction of segment Aq— 3-vector origin of segment Bs— 3-vector direction of segment Beps— precision
Returns
- hit true if segments intersect
- t parameter along A
- u parameter along B
sharp_edges¶
Compute sharp edges of a mesh given a dihedral angle threshold.
Parameters
V— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesangle— dihedral angle threshold in radians (e.g. igl.PI * 0.11)
Returns
- SE #SE by 2 list of sharp edge vertex indices
signed_angle¶
Compute the signed angle subtended by segment AB at point P in 2D.
Parameters
A— 2D position of first endpointB— 2D position of second endpointP— 2D position of query point
Returns
- signed angle in radians
signed_distance¶
signed_distance(P: float64[m, n], V: float64[m, n], F: int64[m, n], sign_type: SignedDistanceType = SignedDistanceType.SIGNED_DISTANCE_TYPE_DEFAULT, lower_bound: float = float('-inf'), upper_bound: float = float('inf')) -> tuple[float64[m], int64[m], float64[m, n], float64[m, n]]
Computes signed distance to a mesh.
Parameters
P— #P by (2|3) list of query point positionsV— #V by (2|3) list of vertex positionsF— #F by ss list of triangle indicessign_type— method for computing distance sign: "pseudonormal", "winding_number", "unsigned", "fast_winding_number", or "default"lower_bound— lower bound of distances needed (default: -inf)upper_bound— upper bound of distances needed (default: inf)
Returns
- Tuple containing: - S: #P list of smallest signed distances - I: #P list of facet indices corresponding to smallest distances - C: #P by (2|3) list of closest points - N: #P by (2|3) list of closest normals (empty unless sign_type="pseudonormal")
slim_precompute¶
slim_precompute(V: float64[m, n], F: int32[m, n], V_init: float64[m, n], slim_energy: MappingEnergyType, b: int32[m], bc: float64[m, n], soft_p: float = 100000.0) -> SLIMData
Precompute data for SLIM optimization.
Parameters
V— #V by 3 list of mesh vertex positionsF— #F by (3|4) list of mesh elements (triangles or tetrahedra)V_init— #V by 3 list of initial mesh vertex positionsslim_energy— Energy to minimizeb— list of boundary indices into Vbc— #b by 3 list of boundary conditionssoft_p— Soft penalty factor (can be zero
slim_solve¶
Run iterations of SLIM optimization.
Parameters
data— Precomputation data structureiter_num— Number of iterations to run
Returns
- #V by 3 list of mesh vertex positions
snap_points¶
Snap query points C to the closest points in V.
Parameters
C— #C by dim list of query positionsV— #V by dim list of data positions
Returns
- I #C list of indices into V of closest points
- minD #C list of squared distances to closest points
- VI #C by dim list of snapped positions (VI = V(I,:))
solid_angle¶
Compute the signed solid angle subtended by oriented triangle (A,B,C) at point P.
Parameters
A— 3D position of first cornerB— 3D position of second cornerC— 3D position of third cornerP— 3D position of query point
Returns
- signed solid angle in steradians
sparse_map_noop¶
"Returns input A
sparse_map_shape¶
"Returns shape of A as 2-vector
sparse_noop¶
"Returns input A
sparse_shape¶
"Returns shape of A as 2-vector
split_nonmanifold¶
Split a non-manifold (or non-orientable) mesh into a orientable manifold mesh possibly with more connected components and geometrically duplicate vertices.
Parameters
F— #F by 3 list of mesh triangle indices into rows of some VSF— #F by 3 list of mesh triangle indices into rows of a new vertex list SV = V(SVI,:)SVI— #SV list of indices into V identifying vertex positions
Split a non-manifold (or non-orientable) mesh into a orientable manifold mesh possibly with more connected components and geometrically duplicate vertices.
Parameters
V— #V by dim explicit list of vertex positionsF— #F by 3 list of mesh triangle indices into rows of some VSV— #SV by dim explicit list of vertex positionsSF— #F by 3 list of mesh triangle indices into rows of a new vertex list SV = V(SVI,:)SVI— #SV list of indices into V identifying vertex positions
squared_edge_lengths¶
Constructs a list of squared lengths of edges opposite each index in a face (triangle/tet) list.
Parameters
V— #V by 3 eigen matrix of vertex positionsF— #F by (2|3|4) list of mesh edges, triangles, or tets
Returns
- L #F by {1|3|6} matrix of squared edge lengths - For edges, a single column of lengths - For triangles, columns correspond to edges [1,2], [2,0], [0,1] - For tets, columns correspond to edges [3 0], [3 1], [3 2], [1 2], [2 0], [0 1]
super_fibonacci¶
Generate n quaternions using Super-Fibonacci Spirals for low-discrepancy SO(3) sampling.
Reference: Super-Fibonacci Spirals: Fast, Low-Discrepancy Sampling of SO(3) [Alexa 2021].
Parameters
n— number of rotations to generate
Returns
- Q n by 4 list of unit quaternions (x, y, z, w)
tet_tet_adjacency¶
Construct tet-tet adjacency for a tet mesh.
Face order: [0,1,2], [0,1,3], [1,2,3], [2,0,3].
Parameters
T— #T by 4 list of tet indices
Returns
- TT #T by 4 matrix; TT(i,j) is the tet adjacent across face j of tet i
- TTi #T by 4 matrix; TTi(i,j) is the local face index in TT(i,j) shared with tet i
tri_tri_intersection_test_3d¶
tri_tri_intersection_test_3d(p1: float64[m, n], q1: float64[m, n], r1: float64[m, n], p2: float64[m, n], q2: float64[m, n], r2: float64[m, n]) -> tuple[bool, bool, float64[m, n], float64[m, n]]
Test if two 3D triangles intersect; if so compute intersection segment.
Parameters
p1,q1,r1— vertices of first trianglep2,q2,r2— vertices of second triangle
Returns
- hit true if triangles intersect
- coplanar true if triangles are coplanar
- source first endpoint of intersection segment
- target second endpoint of intersection segment
tri_tri_overlap_test_3d¶
tri_tri_overlap_test_3d(p1: float64[m, n], q1: float64[m, n], r1: float64[m, n], p2: float64[m, n], q2: float64[m, n], r2: float64[m, n]) -> bool
Test if two 3D triangles overlap (including coplanar case).
Parameters
p1,q1,r1— vertices of first trianglep2,q2,r2— vertices of second triangle
Returns
- true if triangles overlap
triangle_fan¶
Given a list of faces tessellate all of the "exterior" edges forming another list of
Parameters
E— #E by simplex_size-1 list of exterior edges (see exterior_edges.h)cap— #cap by simplex_size list of "faces" tessellating the boundary edges
triangle_triangle_adjacency¶
Constructs the triangle-triangle adjacency matrix for a given mesh (V,F).
Parameters
F— #F by 3 list of mesh faces (must be triangles)TT— #F by 3 adjacent matrix, where each element represents the id of the triangle adjacent to the corresponding edgeTTi— (if return_TTi=True) #F by 3 adjacent matrix, where each element represents the id of the edge of the adjacent triangle that shares an edge with the current triangle - Ifuse_lists=True, returns adjacency data as lists of lists for compatibility with non-manifold meshes.
triangle_triangle_adjacency_lists¶
triangle_triangle_adjacency_lists(F: int64[m, n]) -> tuple[list[list[list[int]]], list[list[list[int]]]]
Constructs the triangle-triangle adjacency matrix for a given mesh (V,F).
Parameters
F— #F by 3 list of mesh faces (must be triangles)TT— #F by 3 adjacent matrix, where each element represents the id of the triangle adjacent to the corresponding edgeTTi— (if return_TTi=True) #F by 3 adjacent matrix, where each element represents the id of the edge of the adjacent triangle that shares an edge with the current triangle - Ifuse_lists=True, returns adjacency data as lists of lists for compatibility with non-manifold meshes.
triangulated_grid¶
Create a regular grid of elements (only 2D supported, currently) Vertex
position order is compatible with igl::grid
Parameters
nx— number of vertices in the x directionny— number of vertices in the y directionGV— nx*ny by 2 list of mesh vertex positions.GF— 2(nx-1)(ny-1) by 3 list of triangle indices
turning_number¶
Compute the turning number of a closed curve in the plane.
Parameters
V— #V by 2 list of 2D vertex positions forming a closed polygon
Returns
- turning number (integer for simple closed curves)
uniformly_sample_two_manifold¶
uniformly_sample_two_manifold(W: float64[m, n], F: int64[m, n], k: int, push: float = 0.1) -> float64[m, n]
Sample a mesh uniformly using furthest-point relaxation in weight space.
Parameters
W— #W by dim positions of mesh in weight spaceF— #F by 3 triangle indicesk— number of samplespush— factor to push samples away from hypercube corners (must be > 0)
Returns
- WS k by dim sample locations in weight space
unique_edge_map¶
Construct relationships between facet "half"-(or rather "viewed")-edges E to unique edges of the mesh seen as a graph.
Parameters
F— #F by 3 list of simplicesE— #F*3 by 2 list of all directed edgesuE— #uE by 2 list of unique undirected edgesEMAP— #F3 list of indices into uE, mapping each directed edge to a unique undirected edge so that uE(EMAP(f+#Fc)) is the unique edge corresponding to E.row(f+#F*c)uE2E— (if return_uE2E=True) #uE list of lists of indices into E of coexisting edges
unique_edge_map_lists¶
Construct relationships between facet "half"-(or rather "viewed")-edges E to unique edges of the mesh seen as a graph.
Parameters
F— #F by 3 list of simplicesE— #F*3 by 2 list of all directed edgesuE— #uE by 2 list of unique undirected edgesEMAP— #F3 list of indices into uE, mapping each directed edge to a unique undirected edge so that uE(EMAP(f+#Fc)) is the unique edge corresponding to E.row(f+#F*c)uE2E— (if return_uE2E=True) #uE list of lists of indices into E of coexisting edges
unique_simplices¶
Find combinatorially unique simplices in F. Order independent.
Parameters
F— #F by simplex-size list of simplicesFF— #FF by simplex-size list of unique simplices in FIA— (if return_IA=True) #FF index vector so that FF == sort(F(IA,:),2)IC— (if return_IC=True) #F index vector so that sort(F,2) == FF(IC,:)
unique_sparse_voxel_corners¶
unique_sparse_voxel_corners(origin: float64[m], h0: float, depth: int, ijk: int64[m, n]) -> tuple[int64[m, n], int64[m, n], float64[m, n]]
Give a list of octree cells subscripts (ijk) (minimum corners) at a given depth, determine a unique list of subscripts to all incident corners of those cells (de-replicating shared corners).
Parameters
origin— 3-vector of root cell minimumh0— side length of current depth leveldepth— current depth (single root cell is depth = 0)ijk— #ijk by 3 list of octree leaf cell minimum corner subscriptsunique_ijk— #unique_ijk by 3 list of unique corner subscriptsJ— #ijk by 8 list of indices into unique_ijk in yxz binary counting orderunique_corners— #unique_ijk by 3 list of unique corner positions
unproject¶
unproject(win: float64[m, n], model: float64[m, n], proj: float64[m, n], viewport: float64[m]) -> float64[m, n]
Eigen reimplementation of gluUnproject for batch processing.
Parameters
win— #P by 3 matrix of screen space x, y, and z coordinatesmodel— 4x4 model-view matrixproj— 4x4 projection matrixviewport— 4-long viewport vector
Returns
- scene #P by 3 matrix of the unprojected x, y, and z coordinates
upsample¶
upsample(V: float64[m, n], F: int64[m, n], number_of_subdivs: int = 1) -> tuple[float64[m, n], int64[m, n]]
Subdivide a mesh without moving vertices using loop subdivision. Returns new vertices and faces.
Parameters
V— #V by dim matrix of mesh verticesF— #F by 3 matrix of triangle facesnumber_of_subdivs— Number of subdivisions (default is 1)
Returns
- A tuple containing: - NV: New vertex positions with original vertices at the top - NF: Matrix of new face indices
upsample_matrix¶
Subdivide a mesh without moving vertices. Returns the subdivision matrix and new faces.
Parameters
n_verts— Number of mesh verticesF— #F by 3 matrix of triangle faces
Returns
- A tuple containing: - S: Sparse subdivision matrix - NF: Matrix of new faces
vector_area_matrix¶
Construct the symmetric vector area matrix A.
[V.col(0)' V.col(1)'] * A * [V.col(0); V.col(1)] is the vector area of mesh (V,F).
Parameters
F— #F by 3 list of triangle indices
Returns
- A 2#V by 2#V sparse symmetric area matrix
vertex_components¶
Compute the connected component ids of each vertex of a mesh given its faces.
Parameters
F— #F by 3 matrix of triangle (face) indices
Returns
- Vector C of per-vertex connected-component ids
vertex_triangle_adjacency¶
vertex_face_adjacency constructs the vertex-face topology of a given mesh (V,F)
Parameters
F— #F by dim list of mesh faces (must be triangles)n— number of vertices #V (e.g.F.maxCoeff()+1orV.rows())VF— #V list of lists of incident faces (adjacency list)VI— #V list of lists of index of incidence within incident faces listed in VF );
vertex_triangle_adjacency_lists¶
vertex_triangle_adjacency_lists(F: int64[m, n], n: int = 0) -> tuple[list[list[int]], list[list[int]]]
vertex_face_adjacency constructs the vertex-face topology of a given mesh (V,F)
Parameters
F— #F by dim list of mesh faces (must be triangles)n— number of vertices #V (e.g.F.maxCoeff()+1orV.rows()) if using listsVF— #V list of lists of incident faces (adjacency list)VI— #V list of lists of index of incidence within incident faces listed in VF
volume¶
Compute volume for tetrahedrons in various input formats.
Parameters
V— #V by dim list of vertex positions or first corner positionsT— #T by 4 list of tet indices
Returns
- vol #T list of tetrahedron volumes
Compute volume for tetrahedrons in various input formats.
Parameters
L— #V by 6 list of edge lengths (see edge_lengths)
Returns
- vol #T list of tetrahedron volumes
volume(A: float64[m, n] = Ellipsis, B: float64[m, n] = Ellipsis, C: float64[m, n] = Ellipsis, D: float64[m, n] = Ellipsis) -> float64[m]
Compute volume for tetrahedrons in various input formats.
Parameters
A— #A by dim list of vertex positions or first corner positionsB— #A by dim list of second corner positionsC— #A by dim list of third corner positionsD— #A by dim list of fourth corner positions
Returns
- vol #T list of tetrahedron volumes
voronoi_mass¶
Compute hybrid Voronoi mass matrix entries for a tetrahedral mesh.
Parameters
V— #V by 3 list of vertex positionsT— #T by 4 list of tet indices into V
Returns
- M #V list of mass matrix diagonal entries (positive for non-degenerate tets)
voxel_grid¶
voxel_grid(V: float64[m, n], offset: float = 0.0, s: int = Ellipsis, pad_count: int = 0) -> tuple[float64[m, n], int64[m]]
Constructs a voxel grid with an offset applied to each cell center.
Parameters
V— Matrix of input verticesoffset— Offset to add to each cell centers— Number of cell centers on the largest sidepad_count— Number of cells beyond the box
Returns
- Tuple (GV, side) where GV contains cell center positions and side defines grid dimensions
winding_number¶
Computes the generalized winding number at each query point with respect to the mesh.
Parameters
V— #V by dim list of mesh vertex positionsF— #F by dim list of mesh facets as indices into rows of VO— #O by dim list of query points
Returns
- Vector of winding numbers for each query point
Computes the generalized winding number at each query point with respect to the mesh.
Parameters
V— #V by dim list of mesh vertex positionsF— #F by dim list of mesh facets as indices into rows of Vo— dim-vector of query point
Returns
- winding number
writeDMAT¶
Write a matrix to a .dmat file in ASCII or binary format.
Parameters
file_name— path to .dmat fileW— Eigen matrix containing coefficients to writeascii— flag for ASCII format (default: true)
Returns
- True if the operation is successful
writeMESH¶
writeMESH(mesh_file_name: str | os.PathLike, V: float64[m, n] = Ellipsis, T: int64[m, n] = Ellipsis, F: int64[m, n] = Ellipsis) -> None
Save a tetrahedral volume mesh to a .mesh file.
Parameters
mesh_file_name— Path to the .mesh file to saveV— #V by 3 matrix of vertex positionsT— #T by 4 matrix of tetrahedral indicesF— #F by 3 matrix of face indices @throws std::runtime_error if file writing fails
writeMSH¶
writeMSH(mesh_file_name: str | os.PathLike, V: float64[m, n] = Ellipsis, Tri: int64[m, n] = Ellipsis, Tet: int64[m, n] = Ellipsis, TriTag: int64[m] = Ellipsis, TetTag: int64[m] = Ellipsis) -> None
Save a tetrahedral volume mesh to a .msh file.
Parameters
mesh_file_name— Path to the .mesh file to saveV— #V by 3 matrix of vertex positionsTri— #Tri by 3 matrix of face indicesTet— #Tet by 4 matrix of tetrahedral indicesTriTag— #Tri vector of face tagsTetTag— #Tet vector of tetrahedral tags @throws std::runtime_error if file writing fails
writeOBJ¶
writeOBJ(filename: str | os.PathLike, V: float64[m, n], F: int64[m, n], CN: float64[m, n] = Ellipsis, FN: int64[m, n] = Ellipsis, TC: float64[m, n] = Ellipsis, FTC: int64[m, n] = Ellipsis) -> None
Write a mesh in an ascii obj file
Parameters
str— path to outputfileV— #V by 3 mesh vertex positionsF— #F by 3|4 mesh indices into VCN— #CN by 3 normal vectorsFN— #F by 3|4 corner normal indices into CNTC— #TC by 2|3 texture coordinatesFTC— #F by 3|4 corner texture coord indices into TC
Returns
- true on success, false on error \bug Horrifyingly, this does not have the same order of parameters as readOBJ.
writeOFF¶
Write a mesh to an ASCII OFF file.
Parameters
filename— path to .off output fileV— #V by 3 list of vertex positionsF— #F by 3 list of triangle indices
Returns
- true on success (raises on failure)
Write a mesh with per-vertex colors to an ASCII OFF file.
Parameters
filename— path to .off output fileV— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesC— #V by 3 list of RGB colors in [0,1]
Returns
- true on success (raises on failure)
writePLY¶
writePLY(filename: str | os.PathLike, V: float64[m, n] = Ellipsis, F: int64[m, n] = Ellipsis, E: int64[m, n] = Ellipsis, N: float64[m, n] = Ellipsis, UV: float64[m, n] = Ellipsis, VD: float64[m, n] = Ellipsis, VDheader: Sequence[str] = [], FD: float64[m, n] = Ellipsis, FDheader: Sequence[str] = [], ED: float64[m, n] = Ellipsis, EDheader: Sequence[str] = [], comments: Sequence[str] = [], encoding: FileEncoding = FileEncoding.Binary) -> None
Write a mesh to a .ply file.
@tparam Derived from Eigen matrix parameters
Parameters
ply_stream— ply file output streamV— (#V,3) matrix of vertex positionsF— (#F,3) list of face indices into vertex positionsE— (#E,2) list of edge indices into vertex positionsN— (#V,3) list of normalsUV— (#V,2) list of texture coordinatesVD— (#V,*) additional vertex dataVheader— (#V) list of vertex data headersFD— (#F,*) additional face dataFheader— (#F) list of face data headersED— (#E,*) additional edge dataEheader— (#E) list of edge data headerscomments— (*) file commentsencoding— - enum, to set binary or ascii file format
writeSTL¶
Write a mesh to an STL file.
Parameters
filename— path to .stl output fileV— #V by 3 list of vertex positionsF— #F by 3 list of triangle indicesbinary— if true, write binary STL; otherwise ASCII
Returns
- true on success (raises on failure)
write_triangle_mesh¶
write_triangle_mesh(filename: str | os.PathLike, V: float64[m, n], F: int64[m, n], encoding: FileEncoding = FileEncoding.Ascii) -> None
write mesh to a file with automatic detection of file format. supported: obj, off, stl, wrl, ply, mesh).
@tparam Scalar type for positions and vectors (will be read as double and cast to Scalar) @tparam Index type for indices (will be read as int and cast to Index)
Parameters
str— path to fileV— eigen double matrix #V by 3F— eigen int matrix #F by 3encoding— set file encoding (ascii or binary) when both are available
AABB¶
AABB.init¶
AABB.find¶
AABB.squared_distance¶
squared_distance(V: float64[m, n], Ele: int64[m, n], P: float64[m, n]) -> tuple[float64[m], int64[m], float64[m, n]]
AABB.intersect_ray_first¶
intersect_ray_first(V: float64[m, n], Ele: int64[m, n], orig: float64[m, n], dir: float64[m, n], min_t: float = float('inf')) -> tuple[int64[m], float64[m], float64[m, n]]
AABB.intersect_ray¶
intersect_ray(V: float64[m, n], Ele: int64[m, n], orig: float64[m, n], dir: float64[m, n]) -> list[list[tuple[int, float, float, float]]]