From 1b65d5b5d8a6505a3205253295c75d627131d6aa Mon Sep 17 00:00:00 2001 From: Teseo Schneider Date: Thu, 4 Jun 2020 17:50:20 -0400 Subject: [PATCH] new documentation --- src/sparse_voxel_grid.cpp | 1 - tutorial/exporter.py | 6 +- tutorial/igl_docs.md | 1189 +++++++++++++++++++++++++++++++++++-- 3 files changed, 1156 insertions(+), 40 deletions(-) diff --git a/src/sparse_voxel_grid.cpp b/src/sparse_voxel_grid.cpp index 2df765e9..1fe3c805 100644 --- a/src/sparse_voxel_grid.cpp +++ b/src/sparse_voxel_grid.cpp @@ -9,7 +9,6 @@ const char *ds_sparse_voxel_grid = R"igl_Qu8mg5v7( -sparse_voxel_grid( p0, scalarFunc, eps, CV, CS, CI ) Given a point, p0, on an isosurface, construct a shell of epsilon sized cubes surrounding the surface. These cubes can be used as the input to marching cubes. diff --git a/tutorial/exporter.py b/tutorial/exporter.py index 26502e45..62c3c026 100644 --- a/tutorial/exporter.py +++ b/tutorial/exporter.py @@ -26,7 +26,11 @@ "the number of positively", "trace(", "Z(known,:)", - "kron(ones(" + "kron(ones(", + "E(i,K(i))", + "I(i) == E(J(i),K(i", + "FF(I,:) = ", + "f(X)" ] def format_data(data): diff --git a/tutorial/igl_docs.md b/tutorial/igl_docs.md index 18810656..2d24e9ba 100644 --- a/tutorial/igl_docs.md +++ b/tutorial/igl_docs.md @@ -57,6 +57,22 @@ u = a - a_diag ``` +### all_pairs_distances +**`all_pairs_distances(u: array, v: array, squared: bool)`** + +compute distances between each point i in V and point j in U + +| | | +|-|-| +|Parameters| V \#V by dim list of points
U \#U by dim list of points
squared whether to return squared distances | +|Returns| D \#V by \#U matrix of distances, where D(i,j) gives the distance or squareed distance between V(i,:) and U(j,:) | + +**Examples** +```python +D = all_pairs_distances(u,v) +``` + + ### ambient_occlusion **`ambient_occlusion(v: array, f: array, p: array, n: array, num_samples: int)`** @@ -183,6 +199,18 @@ b = K * reshape(permute(R,[3 1 2]),size(VF,1)*size(V,2)*size(V,2),1); |See also| arap_linear_block, arap | +### average_onto_faces +**`average_onto_faces(f: array, s: array)`** + +Move a scalar field defined on vertices to faces by averaging + +| | | +|-|-| +|Parameters| f : \#f by ss list of simplexes/faces
s : \#v by dim list of per-vertex values | +|Returns| \#f by dim list of per-face values | +|See also| average_onto_vertices | + + ### average_onto_vertices **`average_onto_vertices(v: array, f: array, s: array)`** @@ -367,6 +395,20 @@ BONE_PARENTS Recover "parent" bones from directed graph representation. |Returns| P \#BE by 1 list of parent indices into BE, -1 means root. | +### boundary_conditions +**`boundary_conditions(v: array, ele: array, c: array, p: array, be: array, ce: array)`** + +Compute boundary conditions for automatic weights computation. This +function expects that the given mesh (V,Ele) has sufficient samples +(vertices) exactly at point handle locations and exactly along bone and +cage edges. + +| | | +|-|-| +|Parameters| V \#V by dim list of domain vertices
Ele \#Ele by simplex-size list of simplex indices
C \#C by dim list of handle positions
P \#P by 1 list of point handle indices into C
BE \#BE by 2 list of bone edge indices into C
CE \#CE by 2 list of cage edge indices into *P* | +|Returns| b \#b list of boundary indices (indices into V of vertices which have
known, fixed values)
bc \#b by \#weights list of known/fixed values for boundary vertices
(notice the \#b != \#weights in general because \#b will include all the
intermediary samples along each bone, etc.. The ordering of the
weights corresponds to [P;BE]
Returns false if boundary conditions are suspicious:
P and BE are empty
bc is empty
some column of bc doesn't have a 0 (assuming bc has >1 columns)
some column of bc doesn't have a 1 (assuming bc has >1 columns) | + + ### boundary_facets **`boundary_facets(t: array)`** @@ -561,6 +603,18 @@ Connect all boundary edges to a fictitious point at infinity. |Parameters| inf_index index of point at infinity (usually V.rows() or F.maxCoeff()) | +### connected_components +**`connected_components(a: sparse_matrix)`** + +Determine the connected components of a graph described by the input +adjacency matrix (similar to MATLAB's graphconncomp). + +| | | +|-|-| +|Parameters| A \#A by \#A adjacency matrix (treated as describing an undirected graph) | +|Returns| Returns number of connected components
C \#A list of component indices into [0,\#K-1]
K \#K list of sizes of each component | + + ### cotmatrix **`cotmatrix(v: array, f: array)`** @@ -592,6 +646,19 @@ COTMATRIX_ENTRIES compute the cotangents of each angle in mesh (V,F) |Returns| C \#F by 3 list of 1/2*cotangents corresponding angles
for triangles, columns correspond to edges [1,2],[2,0],[0,1]
OR
C \#F by 6 list of 1/6*cotangents of dihedral angles*edge lengths
for tets, columns along edges [1,2],[2,0],[0,1],[3,0],[3,1],[3,2] | +### cotmatrix_intrinsic +**`cotmatrix_intrinsic(l: array, f: array)`** + +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 lengths
F \#F by 3 list of face indices into some (not necessarily
determined/embedable) list of vertex positions V. It is assumed \#V ==
F.maxCoeff()+1 | +|Returns| L \#V by \#V sparse Laplacian matrix | +|See also| cotmatrix, intrinsic_delaunay_cotmatrix | + + ### cross_field_mismatch **`cross_field_mismatch(v: array, f: array, pd1: array, pd2: array, is_combed: bool)`** @@ -681,6 +748,27 @@ Given a mesh (v,f) and the integer mismatch of a cross field per edge |See also| cut_mesh | +### cut_to_disk +**`cut_to_disk(f: array) -> List[List[int]]`** + +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 it can be materialized using cut_mesh(). +Implements the triangle-deletion approach described by Gu et al's +"Geometry Images." + +| | | +|-|-| +|Parameters| F \#F by 3 list of the faces (must be triangles) | +|Returns| 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 **`cylinder(axis_devisions: int, height_devisions: int)`** @@ -716,6 +804,18 @@ Deform a skeleton. |Returns| CT \#BE*2 by 3 list of deformed joint positions
BET \#BE by 2 list of bone edge indices (maintains order) | +### delaunay_triangulation +**`delaunay_triangulation(v: array)`** + +Given a set of points in 2D, return a Delaunay triangulation of these +points. + +| | | +|-|-| +|Parameters| V \#V by 2 list of vertex positions | +|Returns| F \#F by 3 of faces in Delaunay triangulation. | + + ### dihedral_angles **`dihedral_angles(v: array, t: array)`** @@ -811,6 +911,32 @@ ears,ear_opp = find_ears(F) ``` +### edge_collapse_is_valid +**`edge_collapse_is_valid(edge: int, F: array, E: array, EMAP: array, EF: array, EI: array) -> bool`** + +Assumes (V,F) is a closed manifold mesh (except for previouslly collapsed faces which should be set to: +[IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL]. +Tests whether collapsing exactly two faces and exactly 3 edges from E (e +and one side of each face gets collapsed to the other) will result in a +mesh with the same topology. + +| | | +|-|-| +|Parameters| e index into E of edge to try to collapse. E(e,:) = [s d] or [d s] so that sF \#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 E
EF \#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). | +|Returns| Returns true if edge collapse is valid | + + +### edge_flaps +**`edge_flaps(f: array)`** + +Determine "edge flaps": two faces on either side of a unique edge (assumes edge-manifold mesh) + +| | | +|-|-| +|Parameters| F \#F by 3 list of face indices | +|Returns| 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 E
EF \#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). | + + ### edge_lengths **`edge_lengths(v: array, f: array)`** @@ -858,6 +984,19 @@ E = igl.edges(F) ``` +### edges_to_path +**`edges_to_path(e: array)`** + +EDGES_TO_PATH Given a set of undirected, unique edges such that all form a +single connected compoent with exactly 0 or 2 nodes with valence =1, +determine the/a path visiting all nodes. + +| | | +|-|-| +|Parameters| E \#E by 2 list of undirected edges | +|Returns| I \#E+1 list of nodes in order tracing the chain (loop), if the output
is a loop then I(1) == I(end)
J \#I-1 list of indices into E of edges tracing I
K \#I-1 list of indices into columns of E {1,2} so that K(i) means that
E(i,K(i)) comes before the other (i.e., E(i,3-K(i)) ). This means that
I(i) == E(J(i),K(i)) for i<\#I, or
I == E(sub2ind(size(E),J([1:end end]),[K;3-K(end)])))) | + + ### euler_characteristic **`euler_characteristic(f: array) -> int`** @@ -890,6 +1029,48 @@ Exact geodesic algorithm for the calculation of geodesics on a triangular mesh. |Notes| Specifying a face as target/source means its center.
Implementation from https:code.google.com/archive/p/geodesic/ with the algorithm first described by Mitchell, Mount and Papadimitriou in 1987. | +### exterior_edges +**`exterior_edges(f: array)`** + +EXTERIOR_EDGES Determines boundary "edges" and also edges with an +odd number of occurrences where seeing edge (i,j) counts as +1 and seeing +the opposite edge (j,i) counts as -1 + +| | | +|-|-| +|Parameters| F \#F by simplex_size list of "faces" | +|Returns| E \#E by simplex_size-1 list of exterior edges | + + +### extract_manifold_patches +**`extract_manifold_patches(f: array)`** + +Extract a set of maximal patches from a given mesh. +A maximal patch is a subset of the input faces that are connected via +manifold edges; a patch is as large as possible. + +| | | +|-|-| +|Parameters| F \#F by 3 list representing triangles. | +|Returns| number of manifold patches.
P \#F list of patch indices. | + + +### extract_non_manifold_edge_curves +**`extract_non_manifold_edge_curves(f: array, u_e2_e: List[List[int]]) -> List[List[int]]`** + +Extract non-manifold curves from a given mesh. +A non-manifold curves are a set of connected non-manifold edges that +does not touch other non-manifold edges except at the end points. +They are also maximal in the sense that they cannot be expanded by +including more edges. +Assumes the input mesh have all -intersection resolved. See ``igl::cgal::remesh__intersection`` for more details. + +| | | +|-|-| +|Parameters| F \#F by 3 list representing triangles.
uE2E \#uE list of lists of indices into E of coexisting edges. | +|Returns| curves An array of arries of unique edge indices. | + + ### face_components **`face_components(f: array)`** @@ -902,6 +1083,82 @@ Compute connected components of facets based on edge-edge adjacency, |See also| vertex_components
vertex_components_from_adjacency_matrix | +### face_occurrences +**`face_occurrences(f: array)`** + +Count the occruances of each face (row) in a list of face indices (irrespecitive of order) + +| | | +|-|-| +|Parameters| F \#F by simplex-size | +|Returns| C \#F list of counts | +|Notes| Known bug: triangles/tets only (where ignoring order still gives simplex) | + + +### faces_first +**`faces_first(v: array, f: array)`** + +FACES_FIRST Reorder vertices so that vertices in face list come before +vertices that don't appear in the face list. This is especially useful if +the face list contains only surface faces and you want surface vertices +listed before internal vertices +[RV,RF,IM] = faces_first(V,T); + +| | | +|-|-| +|Parameters| V \# vertices by 3 vertex positions
F \# faces by 3 list of face indices | +|Returns| RV \# vertices by 3 vertex positions, order such that if the jth vertex is
some face in F, and the kth vertex is not then j comes before k
RF \# faces by 3 list of face indices, reindexed to use RV
IM \#V by 1 list of indices such that: RF = IM(F) and RT = IM(T)
and RV(IM,:) = V | + +**Examples** +```python +Tet mesh in (V,T,F) +``` + + +### faces_first +**`faces_first(V,F,IM);`** + +T = T.unaryExpr(bind1st(mem_fun( static_cast(&VectorXi::operator())), +&IM)).eval(); +### false_barycentric_subdivision +**`false_barycentric_subdivision(v: array, f: array)`** + +Refine the mesh by adding the barycenter of each face + +| | | +|-|-| +|Parameters| V \#V by 3 coordinates of the vertices
F \#F by 3 list of mesh faces (must be triangles) | +|Returns| 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_for_meshes +**`fast_winding_number_for_meshes(v: array, f: array, q: array)`** + +Compute approximate winding number of a triangle soup mesh according to +"Fast Winding Numbers for Soups and Clouds" [Barill et al. 2018]. + +| | | +|-|-| +|Parameters| V \#V by 3 list of mesh vertex positions
F \#F by 3 list of triangle mesh indices into rows of V
Q \#Q by 3 list of query points for the winding number | +|Returns| WN \#Q by 1 list of windinng number values at each query point | + + +### fast_winding_number_for_points +**`fast_winding_number_for_points(p: array, n: array, a: array, q: array)`** + +Evaluate the fast winding number for point data, with default expansion +order and beta (both are set to 2). +This function performes the precomputation and evaluation all in one. +If you need to acess the precomuptation for repeated evaluations, use the +two functions designed for exposed precomputation (described above). + +| | | +|-|-| +|Parameters| P \#P by 3 list of point locations
N \#P by 3 list of point normals
A \#P by 1 list of point areas
Q \#Q by 3 list of query points for the winding number | +|Returns| WN \#Q by 1 list of windinng number values at each query point | + + ### find_cross_field_singularities **`find_cross_field_singularities(v: array, f: array, handle_m_match: array)`** @@ -938,7 +1195,7 @@ This function fits a plane to a point cloud. ### flip_avoiding_line_search -**`flip_avoiding_line_search(f: array, cur_v: array, dst_v: array, energy: lambda function, cur_energy: float)`** +**`flip_avoiding_line_search(f: array, cur_v: array, dst_v: array, energy: Callable[[numpy.ndarray], float], cur_energy: float)`** A bisection line search for a mesh based energy that avoids triangle flips as suggested in "Bijective Parameterization with Free Boundaries" (Smith J. and Schaefer S., 2015). @@ -952,6 +1209,17 @@ Supports both triangle and tet meshes. |Returns| cur_v \#V by dim list of variables at the new location
Returns the energy at the new point | +### flipped_triangles +**`flipped_triangles(v: array, f: array)`** + +Finds the ids of the flipped triangles of the mesh V,F in the UV mapping uv + +| | | +|-|-| +|Parameters| V \#V by 2 list of mesh vertex positions
F \#F by 3 list of mesh faces (must be triangles) | +|Returns| X \#flipped list of containing the indices into F of the flipped triangles | + + ### forward_kinematics **`forward_kinematics(c: array, be: array, p: array, d_q: array, d_t: array)`** @@ -1001,6 +1269,17 @@ g = grad(v, f) ``` +### grad_intrinsic +**`grad_intrinsic(l: array, f: array)`** + +GRAD_INTRINSIC Construct an intrinsic gradient operator. + +| | | +|-|-| +|Parameters| l \#F by 3 list of edge lengths
F \#F by 3 list of triangle indices into some vertex list V | +|Returns| G \#F*2 by \#V gradient matrix: G=[Gx;Gy] where x runs along the 23 edge and
y runs in the counter-clockwise 90° rotation. | + + ### harmonic_weights **`harmonic_weights(v: array, f: array, b: array, bc: array, k: int)`** @@ -1071,6 +1350,32 @@ a∈A b∈B b∈B a∈A |Notes| Known issue: This is only computing max(min(va,B),min(vb,A)). This is
better than max(min(va,Vb),min(vb,Va)). This (at least) is missing
"edge-edge" cases like the distance between the two different
triangulations of a non-planar quad in 3D. Even simpler, consider the
Hausdorff distance between the non-convex, block letter V polygon (with 7
vertices) in 2D and its convex hull. The Hausdorff distance is defined by
the midpoint in the middle of the segment across the concavity and some
non-vertex point _on the edge_ of the V. | +### heat_geodesic +**`heat_geodesic(v: array, f: array, t: float, gamma: array)`** + +Compute fast approximate geodesic distances using precomputed data from a set of selected source vertices (gamma) + +| | | +|-|-| +|Parameters| V \#V by dim list of mesh vertex positions
F \#F by 3 list of mesh face indices into V
t "heat" parameter (smaller --> more accurate, less stable)
gamma \#gamma list of indices into V of source vertices | +|Returns| D \#V list of distances to gamma | + + +### hessian +**`hessian(v: array, f: array)`** + +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. + +| | | +|-|-| +|Parameters| V \#V by dim list of mesh vertex positions
F \#F by 3 list of mesh faces (must be triangles) | +|Returns| H \#V by \#V Hessian energy matrix, each column i corresponding to V(i,:) | + + ### hessian_energy **`hessian_energy(v: array, f: array)`** @@ -1085,6 +1390,39 @@ Natural Boundary Conditions for Smoothing in Geometry Processing |Returns| Q \#V by \#V Hessian energy matrix, each row/column i
corresponding to V(i,:) | +### incircle +**`incircle(pa: array, pb: array, pc: array, pd: array) -> int`** + +Decide whether a point is inside/outside/on a circle. + +| | | +|-|-| +|Parameters| pa, pb, pc 2D points that defines an oriented circle.
pd 2D query point. | +|Returns| INSIDE=1 if pd is inside of the circle defined by pa, pb and pc.
OUSIDE=-1 if pd is outside of the circle.
COCIRCULAR=0 pd is exactly on the circle. | + + +### inradius +**`inradius(v: array, f: array)`** + +Compute the inradius of each triangle in a mesh (V,F) + +| | | +|-|-| +|Parameters| V \#V by dim list of mesh vertex positions
F \#F by 3 list of triangle indices into V | +|Returns| R \#F list of inradii | + + +### insphere +**`insphere(pa: array, pb: array, pc: array, pd: array, pe: array) -> int`** + +Decide whether a point is inside/outside/on a sphere. + +| | | +|-|-| +|Parameters| pa, pb, pc, pd 3D points that defines an oriented sphere.
pe 3D query point. | +|Returns| INSIDE=1 if pe is inside of the sphere defined by pa, pb, pc and pd.
OUSIDE=-1 if pe is outside of the sphere.
COSPHERICAL=0 pe is exactly on the sphere. | + + ### internal_angles **`internal_angles(v: array, f: array)`** @@ -1097,10 +1435,88 @@ Computes internal angles for a triangle mesh. |Notes| If poly-size ≠ 3 then dim must equal 3. | +### intrinsic_delaunay_cotmatrix +**`intrinsic_delaunay_cotmatrix(v: array, f: array)`** + +INTRINSIC_DELAUNAY_COTMATRIX 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 positions
F \#F by 3 list of mesh elements (triangles or tetrahedra) | +|Returns| 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 L
F_intrinsic \#F by 3 list of intrinsic face indices used to compute L | +|See also| intrinsic_delaunay_triangulation, cotmatrix, cotmatrix_intrinsic | + + +### intrinsic_delaunay_triangulation +**`intrinsic_delaunay_triangulation(l_in: array, f_in: array)`** + +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 V | +|Returns| l \#F by 3 list of edge lengths
F \#F by 3 list of new face indices. Note: Combinatorially F may contain
non-manifold edges, duplicate faces and -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. | +|See also| is_intrinsic_delaunay | + + +### intrinsic_delaunay_triangulation_edges +**`intrinsic_delaunay_triangulation_edges(l_in: array, f_in: array)`** + +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 V | +|Returns| E \#F*3 by 2 list of all directed edges, such that E.row(f+\#F*c) is the
edge opposite F(f,c)
uE \#uE by 2 list of unique undirected edges
EMAP \#F*3 list of indices into uE, mapping each directed edge to unique
undirected edge
uE2E \#uE list of lists of indices into E of coexisting edges | +|See also| unique_edge_map | + + +### is_border_vertex +**`is_border_vertex(v: array, f: array) -> List[bool]`** + +Determine vertices on open boundary of a (manifold) mesh with triangle faces F + +| | | +|-|-| +|Parameters| V \#V by dim list of vertex positions
F \#F by 3 list of triangle indices | +|Returns| \#V vector of bools revealing whether vertices are on boundary | +|Notes| Known Bugs:
- assumes mesh is edge manifold | + + +### is_delaunay +**`is_delaunay(v: array, f: array)`** + +IS_DELAUNAY Determine if each edge in the mesh (V,F) is Delaunay. + +| | | +|-|-| +|Parameters| V \#V by dim list of vertex positions
F \#F by 3 list of triangles indices | +|Returns| 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_edge_manifold **`is_edge_manifold(f: array) -> bool`** See is_edge_manifold for the documentation. +### is_intrinsic_delaunay +**`is_intrinsic_delaunay(l: array, f: array)`** + +IS_INTRINSIC_DELAUNAY Determine if each edge in the mesh (V,F) is Delaunay. + +| | | +|-|-| +|Parameters| l \#l by dim list of edge lengths
F \#F by 3 list of triangles indices | +|Returns| 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 **`is_irregular_vertex(v: array, f: array) -> List[bool]`** @@ -1123,6 +1539,24 @@ Constructs isolines for a function z given on a mesh (V,F) |Returns| isoV \#isoV by dim list of isoline vertex positions
isoE \#isoE by 2 list of isoline edge positions | +### iterative_closest_point +**`iterative_closest_point(vx: array, fx: array, vy: array, fy: array, num_samples: int, max_iters: int)`** + +Solve for the rigid transformation that places mesh X onto mesh Y using the +iterative closest point method. In particular, optimize: +min ∫_X inf ‖x*R+t - y‖² dx +R∈SO(3) y∈Y +t∈R³ +Typically optimization strategies include using Gauss Newton +("point-to-plane" linearization) and stochastic descent (sparse random +sampling each iteration). + +| | | +|-|-| +|Parameters| VX \#VX by 3 list of mesh X vertices
FX \#FX by 3 list of mesh X triangle indices into rows of VX
VY \#VY by 3 list of mesh Y vertices
FY \#FY by 3 list of mesh Y triangle indices into rows of VY
num_samples number of random samples to use (larger --> more accurate,
but also more suceptible to sticking to local minimum) | +|Returns| R 3x3 rotation matrix so that (VX*R+t,FX) ~~ (VY,FY)
t 1x3 translation row vector | + + ### lbs_matrix **`lbs_matrix(v: array, w: array)`** @@ -1142,6 +1576,28 @@ kron(ones(1,size(W,2)),[V ones(size(V,1),1)]).*kron(W,ones(1,size(V,2)+1)) ``` +### lexicographic_triangulation +**`lexicographic_triangulation(p: array)`** + +Given a set of points in 2D, return a lexicographic triangulation of these points. + +| | | +|-|-| +|Parameters| P \#P by 2 list of vertex positions | +|Returns| F \#F by 3 of faces in lexicographic triangulation. | + + +### line_segment_in_rectangle +**`line_segment_in_rectangle(s: array, d: array, a: array, b: array) -> bool`** + +Determine whether a line segment overlaps with a rectangle. + +| | | +|-|-| +|Parameters| s source point of line segment
d dest point of line segment
A first corner of rectangle
B opposite corner of rectangle | +|Returns| Returns true if line segment is at all inside rectangle | + + ### local_basis **`local_basis(v: array, f: array)`** @@ -1154,6 +1610,17 @@ Compute a local orthogonal reference system for each triangle in the given mesh. |See also| adjacency_matrix | +### look_at +**`look_at(eye: array, center: array, up: array)`** + +Implementation of the deprecated gluLookAt function. + +| | | +|-|-| +|Parameters| eye 3-vector of eye position
center 3-vector of center reference point
up 3-vector of up vector | +|Returns| R 4x4 rotation matrix | + + ### loop **`loop(v: array, f: array, number_of_subdivs: int = 1)`** @@ -1206,7 +1673,7 @@ Map the vertices whose indices are in a given boundary loop (bnd) on the unit ci ### marching_tets **`marching_tets(TV: array, TT: array, S: array, isovalue: float)`** -performs the marching tetrahedra algorithm on a tet mesh defined by TV and +Performs the marching tetrahedra algorithm on a tet mesh defined by TV and TT with scalar values defined at each vertex in TV. The output is a triangle mesh approximating the isosurface coresponding to the value isovalue. @@ -1214,11 +1681,13 @@ isovalue. | | | |-|-| |Parameters| TV \#tet_vertices x 3 array -- The vertices of the tetrahedral mesh
TT \#tets x 4 array -- The indexes of each tet in the tetrahedral mesh
S \#tet_vertices x 1 array -- The values defined on each tet vertex
isovalue scalar -- The isovalue of the level set we want to compute | -|Returns| SV \#SV x 3 array -- The vertices of the output level surface mesh
SF \#SF x 3 array -- The face indexes of the output level surface mesh | +|Returns| SV : \#SV x 3 array -- The vertices of the output level surface mesh
SF : \#SF x 3 array -- The face indexes of the output level surface mesh
J : \#SF list of indices into TT revealing which tet each face comes from
BC : \#SV x \#TV list of barycentric coordinates so that SV = BC*TV | +**Examples** +```python +sv, sf, j, bc = igl.marching_tets(tv, tt, s, isovalue) +``` -### marching_tets -**`marching_tets( TV, TT, S, isovalue, SV, SF)`** ### massmatrix **`massmatrix(v: array, f: array, type: int = 1)`** @@ -1232,6 +1701,18 @@ Constructs the mass (area) matrix for a given mesh (V,F). |See also| adjacency_matrix, cotmatrix, grad | +### massmatrix_intrinsic +**`massmatrix_intrinsic(l: array, f: array, type: int = 1)`** + +Constructs the mass (area) matrix for a given mesh (V,F). + +| | | +|-|-| +|Parameters| l \#l by simplex_size list of mesh edge lengths
F \#F by simplex_size list of mesh elements (triangles or tetrahedra)
type one of the following ints:
-igl.MASSMATRIX_TYPE_BARYCENTRIC barycentric
-igl.MASSMATRIX_TYPE_VORONOI voronoi-hybrid (default)
-igl.MASSMATRIX_TYPE_FULL full (not implemented) | +|Returns| M \#V by \#V mass matrix | +|See also| adjacency_matrix | + + ### min_quad_with_fixed **`min_quad_with_fixed(A: sparse_matrix, B: array, known: array, Y: array, Aeq: sparse_matrix, Beq: array, is_A_pd: bool)`** @@ -1247,15 +1728,36 @@ Aeq*Z = Beq |Returns| Z n by k solution | -### nrosy -**`nrosy(v: array, f: array, b: array, bc: array, b_soft: array, w_soft: array, bc_soft: array, n: int, soft: float)`** +### mvc +**`mvc(v: array, c: array)`** + +MEAN VALUE COORDINATES + +| | | +|-|-| +|Parameters| V \#V x dim list of vertex positions (dim = 2 or dim = 3)
C \#C x dim list of polygon vertex positions in counter-clockwise order (dim = 2 or dim = 3) | +|Returns| W weights, \#V by \#C matrix of weights | +|Notes| Known Bugs: implementation is listed as "Broken" | + +**Examples** +```python +W = mvc(V,C) +``` + + +### normal_derivative +**`normal_derivative(v: array, f: array)`** -Generate a N-RoSy field from a sparse set of constraints. +NORMAL_DERIVATIVE Computes the directional derivative **normal** to +**all** (half-)edges of a triangle mesh (not just boundary edges). These +are integrated along the edge: they're the per-face constant gradient dot +the rotated edge vector (unit rotated edge vector for direction then +magnitude for integration). | | | |-|-| -|Parameters| v : \#v by 3 array of mesh vertex coordinates
f : \#f by 3 array of mesh faces (must be triangles)
b : \#b by 1 array of constrained face indices
bc : \#b by 3 array of representative vectors for the constrained faces
b_soft : \#s by 1 b for soft constraints
w_soft : \#s by 1 weight for the soft constraints (0-1)
bc_soft : \#s by 3 bc for soft constraints
n : the degree of the N-RoSy vector field
soft : the strength of the soft constraints w.r.t. smoothness (0 -> smoothness only, 1->constraints only) | -|Returns| r : \#f by 3 the representative vectors of the interpolated field
S : \#v by 1 the singularity index for each vertex (0 = regular) | +|Parameters| V \#V by dim list of mesh vertex positions
F \#F by 34 list of triangletetrahedron indices into V | +|Returns| DD \#F*34 by \#V sparse matrix representing operator to compute
directional derivative with respect to each facet of each element. | ### offset_surface @@ -1270,24 +1772,58 @@ signed distance values from the input triangle mesh. |Returns| 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" from `isolevel` these values are incorrect) | -### orientable_patches -**`orientable_patches(f: array)`** +### orient2d +**`orient2d(pa: array, pb: array, pc: array) -> int`** -Compute connected components of facets connected by manifold edges. +Compute the orientation of the triangle formed by pa, pb, pc. | | | |-|-| -|Parameters| f : n by dim array of face ids | -|Returns| A tuple (c, A) where c is an array of component ids (starting with 0)
and A is a \#f x \#f adjacency matri | -|See also| components | -|Notes| Known bugs: This will detect a moebius strip as a single patch (manifold, non-orientable) and also non-manfiold, yet orientable patches. | +|Parameters| pa, pb, pc 2D points. | +|Returns| POSITIVE=1 if pa, pb, pc are counterclockwise oriented.
NEGATIVE=-1 if they are clockwise oriented.
COLLINEAR=0 if they are collinear. | -### oriented_facets -**`oriented_facets(f: array)`** +### orient3d +**`orient3d(pa: array, pb: array, pc: array, pd: array) -> int`** -Determines all 'directed [facets](https:en.wikipedia.org/wiki/Simplex#Elements)' of a given set -of simplicial elements. For a manifold triangle mesh, this computes all half-edges. +Compute the orientation of the tetrahedron formed by pa, pb, pc, pd. + +| | | +|-|-| +|Parameters| pa, pb, pc, pd 3D points. | +|Returns| POSITIVE=1 if pd is "below" the oriented plane formed by pa, pb and pc.
NEGATIVE=-1 if pd is "above" the plane.
COPLANAR=0 if pd is on the plane. | + + +### orient_outward +**`orient_outward(v: array, f: array, c: array)`** + +Orient each component (identified by C) of a mesh (V,F) so the normals on +average point away from the patch's centroid. + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of triangle indices
C \#F list of components (output of orientable_patches) | +|Returns| FF \#F by 3 list of new triangle indices such that FF(~I,:) = F(~I,:) and
FF(I,:) = fliplr(F(I,:)) (OK if &FF = &F)
I max(C)+1 list of whether face has been flipped | + + +### orientable_patches +**`orientable_patches(f: array)`** + +Compute connected components of facets connected by manifold edges. + +| | | +|-|-| +|Parameters| f : n by dim array of face ids | +|Returns| A tuple (c, A) where c is an array of component ids (starting with 0)
and A is a \#f x \#f adjacency matri | +|See also| components | +|Notes| Known bugs: This will detect a moebius strip as a single patch (manifold, non-orientable) and also non-manfiold, yet orientable patches. | + + +### oriented_facets +**`oriented_facets(f: array)`** + +Determines all 'directed [facets](https:en.wikipedia.org/wiki/Simplex#Elements)' of a given set +of simplicial elements. For a manifold triangle mesh, this computes all half-edges. For a manifold tetrahedral mesh, this computes all half-faces. | | | @@ -1298,6 +1834,79 @@ For a manifold tetrahedral mesh, this computes all half-faces. |Notes| This is not the same as igl::edges because this includes every
directed edge including repeats (meaning interior edges on a surface will
show up once for each direction and non-manifold edges may appear more than
once for each direction). | +### outer_edge +**`outer_edge(v: array, f: array, i: array)`** + +Find an edge that is reachable from infinity without crossing any faces. +Such edge is called "outer edge." +Precondition: The input mesh must have all -intersection resolved and +no duplicated vertices. The correctness of the output depends on the fact +that there is no edge overlap. See cgal::remesh__intersections.h for +how to obtain such input. + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of triangle indices into V
I \#I list of facets to consider | +|Returns| v1 index of the first end point of outer edge
v2 index of the second end point of outer edge
A \#A list of facets incident to the outer edge | + + +### outer_facet +**`outer_facet(v: array, f: array, n: array, i: array)`** + +Find a facet that is reachable from infinity without crossing any faces. +Such facet is called "outer facet." +Precondition: The input mesh must have all -intersection resolved. I.e +there is no duplicated vertices, no overlapping edge and no intersecting +faces (the only exception is there could be topologically duplicated faces). +See cgal::remesh__intersections.h for how to obtain such input. + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of triangle indices into V
N \#N by 3 list of face normals
I \#I list of facets to consider | +|Returns| f Index of the outer facet.
flipped true iff the normal of f points inwards. | + + +### outer_vertex +**`outer_vertex(v: array, f: array, i: array)`** + +Find a vertex that is reachable from infinite without crossing any faces. +Such vertex is called "outer vertex." +Precondition: The input mesh must have all -intersection resolved and +no duplicated vertices. See cgal::remesh__intersections.h for how to +obtain such input. + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of triangle indices into V
I \#I list of facets to consider | +|Returns| v_index index of outer vertex
A \#A list of facets incident to the outer vertex | + + +### partition +**`partition(w: array, k: int)`** + +PARTITION partition vertices into groups based on each +vertex's vector: vertices with similar coordinates (close in +space) will be put in the same group. + +| | | +|-|-| +|Parameters| W \#W by dim coordinate matrix
k desired number of groups default is dim | +|Returns| G \#W list of group indices (1 to k) for each vertex, such that vertex i is assigned to group G(i)
S k list of seed vertices
D \#W list of squared distances for each vertex to it's corresponding closest seed | + + +### path_to_edges +**`path_to_edges(i: array, make_loop: bool = False)`** + +Given a path as an ordered list of N>=2 vertex indices I[0], I[1], ..., I[N-1] +construct a list of edges [[I[0],I[1]], [I[1],I[2]], ..., [I[N-2], I[N-1]]] +connecting each sequential pair of vertices. + +| | | +|-|-| +|Parameters| I \#I list of vertex indices
make_loop bool If true, include an edge connecting I[N-1] to I[0] | +|Returns| E \#I-1 by 2 list of edges | + + ### per_edge_normals **`per_edge_normals(v: array, f: array, weight: int = 0, fn: array)`** @@ -1386,6 +1995,29 @@ Planarize a quad mesh. |Returns| out : \#v by 3 array of planar mesh vertex 3D positions | +### point_in_circle +**`point_in_circle(qx: float, qy: float, cx: float, cy: float, r: float) -> bool`** + +Determine if 2d point is in a circle + +| | | +|-|-| +|Parameters| qx x-coordinate of query point
qy y-coordinate of query point
cx x-coordinate of circle center
cy y-coordinate of circle center
r radius of circle | +|Returns| Returns true if query point is in circle, false otherwise | + + +### point_in_poly +**`point_in_poly(poly: List[List[int]], xt: int, yt: int) -> bool`** + +Determine if 2d point is inside a 2D polygon + +| | | +|-|-| +|Parameters| poly vector of polygon points, [0]=x, [1]=y. Polyline need not be closed (i.e. first point != last point), the line segment between last and first selected points is constructed within this function.
x x-coordinate of query point
y y-coordinate of query point | +|Returns| Returns true if query point is in polygon, false otherwise | +|Notes| From http:www.visibone.com/inpoly/ | + + ### point_mesh_squared_distance **`point_mesh_squared_distance(p: array, v: array, ele: array)`** @@ -1398,6 +2030,51 @@ Compute distances from a set of points P to a triangle mesh (V,F) |Notes| Known bugs: This only computes distances to given primitivess. 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. | +### point_simplex_squared_distance +**`point_simplex_squared_distance(p: array, v: array, ele: array, i: int)`** + +Determine squared distance from a point to linear simplex. +Also return barycentric coordinate of closest point. + +| | | +|-|-| +|Parameters| p d-long query point
V \#V by d list of vertices
Ele \#Ele by ss<=d+1 list of simplex indices into V
i index into Ele of simplex | +|Returns| sqr_d squared distance of Ele(i) to p
c closest point on Ele(i)
b barycentric coordinates of closest point on Ele(i) | + + +### polar_dec +**`polar_dec(a: array)`** + +Computes the polar decomposition (R,T) of a matrix A + +| | | +|-|-| +|Parameters| A 3 by 3 matrix to be decomposed | +|Returns| R 3 by 3 orthonormal matrix part of decomposition
T 3 by 3 stretch matrix part of decomposition | + + +### polygon_mesh_to_triangle_mesh +**`polygon_mesh_to_triangle_mesh(p: array)`** + +Triangulate a general polygonal mesh into a triangle mesh. + +| | | +|-|-| +|Parameters| vF matrix polygon index lists | +|Returns| F eigen int matrix \#F by 3 | + + +### polygon_mesh_to_triangle_mesh_from_list +**`polygon_mesh_to_triangle_mesh_from_list(v_f: List[List[int]])`** + +Triangulate a general polygonal mesh into a triangle mesh. + +| | | +|-|-| +|Parameters| vF list of polygon index lists | +|Returns| F eigen int matrix \#F by 3 | + + ### principal_curvature **`principal_curvature(v: array, f: array, radius: int = 5, use_k_ring: bool = True)`** @@ -1441,6 +2118,85 @@ MatrixXd Xprime = (X * R).rowwise() + t.transpose(); ``` +### project +**`project(v: array, model: array, proj: array, viewport: array)`** + +Project + +| | | +|-|-| +|Parameters| V \#V by 3 list of object points
model model matrix
proj projection matrix
viewport viewport vector | +|Returns| P \#V by 3 list of screen space points | + + +### project_isometrically_to_plane +**`project_isometrically_to_plane(v: array, f: array)`** + +Project each triangle to the plane + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of mesh indices | +|Returns| U \#F*3 by 2 list of triangle positions
UF \#F by 3 list of mesh indices into U
I \#V by \#F*3 such that I(i,j) = 1 implies U(j,:) corresponds to V(i,:) | + +**Examples** +```python +[U,UF,I] = project_isometrically_to_plane(V,F) +``` + + +### project_to_line +**`project_to_line(p: array, s: array, d: array)`** + +PROJECT_TO_LINE project points onto vectors, that is find the parameter +t for a point p such that proj_p = (y-x).*t, additionally compute the +squared distance from p to the line of the vector, such that +p - proj_p² = sqr_d + +| | | +|-|-| +|Parameters| P \#P by dim list of points to be projected
S size dim start position of line vector
D size dim destination position of line vector | +|Returns| T \#P by 1 list of parameters
sqrD \#P by 1 list of squared distances | + +**Examples** +```python +[T,sqrD] = project_to_line(P,S,D) +``` + + +### project_to_line_segment +**`project_to_line_segment(p: array, s: array, d: array)`** + +PROJECT_TO_LINE_SEGMENT project points onto vectors, that is find the parameter +t for a point p such that proj_p = (y-x).*t, additionally compute the +squared distance from p to the line of the vector, such that +p - proj_p² = sqr_d + +| | | +|-|-| +|Parameters| P \#P by dim list of points to be projected
S size dim start position of line vector
D size dim destination position of line vector | +|Returns| T \#P by 1 list of parameters
sqrD \#P by 1 list of squared distances | + +**Examples** +```python +[T,sqrD] = project_to_line_segment(P,S,D) +``` + + +### pso +**`pso(f: Callable[[numpy.ndarray[float64[m, 1]]], float], lb: numpy.ndarray, ub: numpy.ndarray, max_iters: int, population: int)`** + +Solve the problem: +minimize f(x) +subject to lb ≤ x ≤ ub +by particle swarm optimization (PSO). + +| | | +|-|-| +|Parameters| f function that evaluates the objective for a given "particle" location
LB \#X vector of lower bounds
UB \#X vector of upper bounds
max_iters maximum number of iterations
population number of particles in swarm | +|Returns| f(X) objective corresponding to best particle seen so far
X best particle seen so far | + + ### qslim **`qslim(v: array, f: array, max_m: int)`** @@ -1455,6 +2211,18 @@ mesh can have open boundaries but should be edge-manifold. |Returns| 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 face
I \#U list of indices into V of birth vertices | +### quad_grid +**`quad_grid(nx: int, ny: int)`** + +Generate a quad mesh over a regular grid. + +| | | +|-|-| +|Parameters| nx number of vertices in the x direction
ny number of vertices in the y direction | +|Returns| V nx*ny by 2 list of vertex positions
Q (nx-1)*(ny-1) by 4 list of quad indices into V
E (nx-1)*ny+(ny-1)*nx by 2 list of undirected quad edge indices into V | +|See also| grid, triangulated_grid | + + ### quad_planarity **`quad_planarity(v: array, f: array)`** @@ -1466,6 +2234,18 @@ Compute planarity of the faces of a quad mesh. |Returns| p : \#f by 1 array of mesh face (quad) planarities | +### ramer_douglas_peucker +**`ramer_douglas_peucker(p: array, tol: float)`** + +Run (Ramer-)Duglass-Peucker curve simplification but keep track of where +every point on the original curve maps to on the simplified curve. + +| | | +|-|-| +|Parameters| P \#P by dim list of points, (use P([1:end 1],:) for loops)
tol DP tolerance | +|Returns| S \#S by dim list of points along simplified curve
J \#S indices into P of simplified points
Q \#P by dim list of points mapping along simplified curve | + + ### random_points_on_mesh **`random_points_on_mesh(n: int, v: array, f: array)`** @@ -1477,6 +2257,54 @@ RANDOM_POINTS_ON_MESH Randomly sample a mesh (V,F) n times. |Returns| B n by 3 list of barycentric coordinates, ith row are coordinates of
ith sampled point in face FI(i)
FI n list of indices into F | +### random_search +**`random_search(f: Callable[[numpy.ndarray[float64[m, 1]]], float], lb: numpy.ndarray, ub: numpy.ndarray, iters: int)`** + +Solve the problem: +minimize f(x) +subject to lb ≤ x ≤ ub +by uniform random search. + +| | | +|-|-| +|Parameters| f function to minimize
LB \#X vector of finite lower bounds
UB \#X vector of finite upper bounds
iters number of iterations | +|Returns| f(X)
X \#X optimal parameter vector | + + +### ray_box_intersect +**`ray_box_intersect(source: array, dir: array, box_min: array, box_max: array, t0: float, t1: float)`** + +Determine whether a ray origin+t*dir and box intersect within the ray's parameterized +range (t0,t1) + +| | | +|-|-| +|Parameters| source 3-vector origin of ray
dir 3-vector direction of ray
box_min min axis aligned box
box_max max axis aligned box
t0 hit only if hit.t less than t0
t1 hit only if hit.t greater than t1 | +|Returns| true if hit
tmin minimum of interval of overlap within [t0,t1]
tmax maximum of interval of overlap within [t0,t1] | + + +### ray_mesh_intersect +**`ray_mesh_intersect(source: array, dir: array, v: array, f: array) -> List[Tuple[int, int, float, float, float]]`** + +Shoot a ray against a mesh (V,F) and collect the first hit. + +| | | +|-|-| +|Parameters| source 3-vector origin of ray
dir 3-vector direction of ray
V \#V by 3 list of mesh vertex positions
F \#F by 3 list of mesh face indices into V | +|Returns| hits **sorted** list of hits: id, gid, u, v, t | + + +### ray_sphere_intersect +**`ray_sphere_intersect(source: array, dir: array, center: array, r: float)`** + +Compute the intersection between a ray from O in direction D and a sphere centered at C with radius r + +| | | +|-|-| +|Parameters| source origin of ray
dir direction of ray
center center of sphere
r radius of sphere | +|Returns| Returns the number of hits
t0 parameterization of first hit (set only if exists) so that hit position = o + t0*d
t1 parameterization of second hit (set only if exists) | + + ### read_dmat **`read_dmat(filename: str, dtype: dtype = 'float64')`** @@ -1496,6 +2324,34 @@ w = read_dmat("my_model.dmat") ``` +### read_mesh +**`read_mesh(filename: str, dtypef: dtype = 'float')`** + +Load a tetrahedral volume mesh from a .mesh file. + +| | | +|-|-| +|Parameters| filename : path of .mesh file
dtype : data-type of the returned vertices, optional. Default is `float64`.
(returned faces always have type int32.) | +|Returns| v : array of vertex positions \#v by 3
t : \#t by 4 array of tet indices into vertex positions
f : \#f by 3 array of face indices into vertex positions | +|Notes| Known bugs: Holes and regions are not supported | + +**Examples** +```python +v, t, f = read_mesh("my_mesh.mesh") +``` + + +### read_msh +**`read_msh(filename: str, dtypef: dtype = 'float')`** + +Read a mesh (e.g., tet mesh) from a gmsh .msh file + +| | | +|-|-| +|Parameters| filename path to .msh file
dtype : data-type of the returned vertices, optional. Default is `float64`.
(returned faces always have type int32.) | +|Returns| V \#V by 3 list of 3D mesh vertex positions
T \#T by ss list of 3D ss-element indices into V (e.g., ss=4 for tets) | + + ### read_obj **`read_obj(filename: str, dtype: dtype = 'float64')`** @@ -1631,6 +2487,22 @@ An exception will be thrown. |Returns| F2 \#F2 by 3 array of output faces without duplicated faces.
J \#F2 list of indices into F1. | +### rigid_alignment +**`rigid_alignment(x: array, p: array, n: array)`** + +Find the rigid transformation that best aligns the 3D points X to their +corresponding points P with associated normals N. +min ‖(X*R+t-P)'N‖² +R∈SO(3) +t∈R³ + +| | | +|-|-| +|Parameters| X \#X by 3 list of query points
P \#X by 3 list of corresponding (e.g., closest) points
N \#X by 3 list of unit normals for each row in P | +|Returns| R 3 by 3 rotation matrix
t 1 by 3 translation vector | +|See also| icp | + + ### rotate_vectors **`rotate_vectors(v: array, a: array, b1: array, b2: array)`** @@ -1642,6 +2514,18 @@ Rotate the vectors V by A radiants on the tangent plane spanned by B1 and B2 |Returns| Returns the rotated vectors | +### sample_edges +**`sample_edges(v: array, e: array, k: int)`** + +Compute samples_per_edge extra points along each edge in E defined over +vertices of V. + +| | | +|-|-| +|Parameters| V vertices over which edges are defined, \# vertices by dim
E edge list, \# edges by 2
k number of extra samples to be computed along edge not including start and end points | +|Returns| S sampled vertices, size less than \# edges * (2+k) by dim always begins
with V so that E is also defined over S | + + ### segments_intersect **`segments_intersect(p: array, r: array, q: array, s: array)`** @@ -1669,6 +2553,28 @@ cone and a _uniform_ average (_not_ a average weighted by inverse angles). |Returns| S \#P list of shape diamater function values between bounding box
diagonal (perfect sphere) and 0 (perfect needle hook) | +### sharp_edges +**`sharp_edges(v: array, f: array, angle: float)`** + +SHARP_EDGES Given a mesh, compute sharp edges. + +| | | +|-|-| +|Parameters| V \#V by 3 list of vertex positions
F \#F by 3 list of triangle mesh indices into V
angle dihedral angle considered to sharp (e.g., igl::PI * 0.11) | +|Returns| SE \#SE by 2 list of edge indices into V
E \#e by 2 list of edges in no particular order
uE \#uE by 2 list of unique undirected edges
EMAP \#F*3 list of indices into uE, mapping each directed edge to unique
undirected edge so that uE(EMAP(f+\#F*c)) is the unique edge
corresponding to E.row(f+\#F*c)
uE2E \#uE list of lists of indices into E of coexisting edges, so that
E.row(uE2E[i][j]) corresponds to uE.row(i) for all j in
0..uE2E[i].size()-1.
sharp \#SE list of indices into uE revealing sharp undirected edges | + + +### signed_angle +**`signed_angle(a: array, b: array, p: array) -> float`** + +Compute the signed angle subtended by the oriented 3d triangle (A,B,C) at some point P + +| | | +|-|-| +|Parameters| A 2D position of corner
B 2D position of corner
P 2D position of query point | +|Returns| returns signed angle | + + ### signed_distance **`signed_distance(p: array, v: array, f: array, return_normals: bool = False) -> tuple`** @@ -1686,6 +2592,44 @@ S, I, C = signed_distance(P, V, F, return_normals=False) ``` +### simplify_polyhedron +**`simplify_polyhedron(ov: array, of: array)`** + +Simplify a polyhedron represented as a triangle mesh (OV,OF) by collapsing +any edge that doesn't contribute to defining surface's pointset. This +_would_ also make sense for open and non-manifold meshes, but the current +implementation only works with closed manifold surfaces with well defined +triangle normals. + +| | | +|-|-| +|Parameters| OV \#OV by 3 list of input mesh vertex positions
OF \#OF by 3 list of input mesh triangle indices into OV | +|Returns| V \#V by 3 list of output mesh vertex positions
F \#F by 3 list of input mesh triangle indices into V
J \#F list of indices into OF of birth parents | + + +### snap_points +**`snap_points(c: array, v: array)`** + +SNAP_POINTS snap list of points C to closest of another list of points V +[I,minD,VI] = snap_points(C,V) + +| | | +|-|-| +|Parameters| C \#C by dim list of query point positions
V \#V by dim list of data point positions | +|Returns| I \#C list of indices into V of closest points to C
minD \#C list of squared (^p) distances to closest points
VI \#C by dim list of new point positions, VI = V(I,:) | + + +### solid_angle +**`solid_angle(a: array, b: array, c: array, p: array) -> float`** + +Compute the signed solid angle subtended by the oriented 3d triangle (A,B,C) at some point P + +| | | +|-|-| +|Parameters| A 3D position of corner
B 3D position of corner
C 3D position of corner
P 3D position of query point | +|Returns| Returns signed solid angle | + + ### sort_angles **`sort_angles(m: array)`** @@ -1699,6 +2643,30 @@ Instead of computing angles using atan2(y, x), sort directly on (y, x). |Notes| None. | +### sparse_voxel_grid +**`sparse_voxel_grid(p0: numpy.ndarray, scalar_func: Callable[[numpy.ndarray[float64[1, 3]]], float], eps: float, expected_number_of_cubes: int)`** + +Given a point, p0, on an isosurface, construct a shell of epsilon sized cubes surrounding the surface. +These cubes can be used as the input to marching cubes. + +| | | +|-|-| +|Parameters| p0 A 3D point on the isosurface surface defined by scalarFunc(x) = 0
scalarFunc A scalar function from R^3 to R -- points which map to 0 lie
on the surface, points which are negative lie inside the surface,
and points which are positive lie outside the surface
eps The edge length of the cubes surrounding the surface
expected_number_of_cubes This pre-allocates internal data structures to speed things up | +|Returns| CS \#cube-vertices by 1 list of scalar values at the cube vertices
CV \#cube-vertices by 3 list of cube vertex positions
CI \#number of cubes by 8 list of indexes into CS and CV. Each row represents a cube | + + +### swept_volume_bounding_box +**`swept_volume_bounding_box(n: int, v: Callable[[int, float], numpy.ndarray[float64[1, 3]]], steps: int)`** + +Construct an axis-aligned bounding box containing a shape undergoing a +motion sampled at `steps` discrete momements. + +| | | +|-|-| +|Parameters| n number of mesh vertices
V function handle so that V(i,t) returns the 3d position of vertex i at time t, for t∈[0,1]
steps number of time steps: steps=3 --> t∈{0,0.5,1} | +|Returns| min,max corners of box containing mesh under motion | + + ### tet_tet_adjacency **`tet_tet_adjacency(t: array)`** @@ -1711,16 +2679,28 @@ Constructs the tet_tet adjacency matrix for a given tet mesh with tets T |Notes| the first face of a tet is [0,1,2], the second [0,1,3], the third [1,2,3], and the fourth [2,0,3]. | -### tetrahedralize -**`tetrahedralize(v: array, f: array, switches: str = 'pYQ')`** +### topological_hole_fill +**`topological_hole_fill(f: array, b: array, holes: List[List[int]])`** -Mesh the interior of a surface mesh (V,F) using tetgen. +Topological fill hole on a mesh, with one additional vertex each hole +Index of new abstract vertices will be F.maxCoeff() + (index of hole) | | | |-|-| -|Parameters| v : \#v by 3 vertex position array
f : \#v array of polygon face indices into V (0-indexed)
switches : string of tetgen options (See tetgen documentation) e.g.
"pq1.414a0.01" tries to mesh the interior of a given surface with quality and area constraints. Will mesh the convex hull constrained to pass through V (ignores F) | -|Returns| tv \#v by 3 vertex position array
tt \#t by 4 array of tet face indices
tf \#f by 3 array of triangle face indices | -|Notes| Returns status:
0 success
1 tetgen threw exception
2 tetgen did not crash but could not create any tets (probably there are
holes, duplicate faces etc.)
-1 other error | +|Parameters| F \#F by simplex-size list of element indices
b \#b boundary indices to preserve
holes vector of hole loops to fill | +|Returns| F_filled input F stacked with filled triangles. | + + +### triangle_fan +**`triangle_fan(e: array)`** + +Given a list of faces tessellate all of the "exterior" edges forming another +list of + +| | | +|-|-| +|Parameters| E \#E by 2 list of exterior edges (see exterior_edges.h) | +|Returns| cap \#cap by simplex_size list of "faces" tessellating the boundary edges | ### triangle_triangle_adjacency @@ -1736,20 +2716,41 @@ mesh (V,F). |Notes| NOTE: the first edge of a triangle is [0,1] the second [1,2] and the third
[2,3]. this convention is DIFFERENT from cotmatrix_entries.h | -### triangulate -**`triangulate(v: array, e: array, h: array, flags: str = 'a0.005qQ')`** +### triangles_from_strip +**`triangles_from_strip(s: array)`** -Triangulate the interior of a polygon using the triangle library. +TRIANGLES_FROM_STRIP Create a list of triangles from a stream of indices +along a strip. | | | |-|-| -|Parameters| v : \#v by 2 array of 2D vertex positions
e : \#e by 2 array of vertex ids forming unoriented edges of the boundary of the polygon
h : \#h by 2 coordinates of points contained inside holes of the polygon
m : optional \#v list of markers for input vertices
flags : string of options pass to triangle (see triangle documentation) (default 'a0.005q') | -|Returns| v2 : \#v2 by 2 coordinates of the vertives of the generated triangulation
f2 : \#f2 by 3 array of indices forming the faces of the generated triangulation
m2 : (only if you passed in m) \#v2 list of markers for output vertices | +|Parameters| S \#S list of indices | +|Returns| F \#S-2 by 3 list of triangle indices | -**Examples** -```python -v2, f2 = triangulate(v, e, h) -``` + +### triangulated_grid +**`triangulated_grid(nx: int, ny: int)`** + +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 direction
ny number of vertices in the y direction | +|Returns| GV nx*ny by 2 list of mesh vertex positions.
GF 2*(nx-1)*(ny-1) by 3 list of triangle indices | +|See also| grid, quad_grid | + + +### two_axis_valuator_fixed_up +**`two_axis_valuator_fixed_up(w: int, h: int, speed: float, down_quat: array, down_x: int, down_y: int, mouse_x: int, mouse_y: int)`** + +Applies a two-axis valuator drag rotation (as seen in Maya/Studio max) to a given rotation. + +| | | +|-|-| +|Parameters| w width of the trackball context
h height of the trackball context
speed controls how fast the trackball feels, 1 is normal
down_quat rotation at mouse down, i.e. the rotation we're applying the
trackball motion to (as quaternion). **Note:** Up-vector that is fixed
is with respect to this rotation.
down_x position of mouse down
down_y position of mouse down
mouse_x current x position of mouse
mouse_y current y position of mouse | +|Returns| quat the resulting rotation (as quaternion) | +|See also| snap_to_fixed_up | ### uniformly_sample_two_manifold_at_vertices @@ -1776,6 +2777,29 @@ Transformations" |Returns| WS k by dim locations in weights space | +### unique_edge_map +**`unique_edge_map(f: array)`** + +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 simplices | +|Returns| E \#F*3 by 2 list of all directed edges, such that E.row(f+\#F*c) is the
edge opposite F(f,c)
uE \#uE by 2 list of unique undirected edges
EMAP \#F*3 list of indices into uE, mapping each directed edge to unique
undirected edge so that uE(EMAP(f+\#F*c)) is the unique edge
corresponding to E.row(f+\#F*c)
uE2E \#uE list of lists of indices into E of coexisting edges, so that
E.row(uE2E[i][j]) corresponds to uE.row(i) for all j in
0..uE2E[i].size()-1. | + + +### unique_simplices +**`unique_simplices(f: array)`** + +Find *combinatorially* unique simplices in F. **Order independent** + +| | | +|-|-| +|Parameters| F \#F by simplex-size list of simplices | +|Returns| FF \#FF by simplex-size list of unique simplices in F
IA \#FF index vector so that FF == sort(F(IA,:),2);
IC \#F index vector so that sort(F,2) == FF(IC,:); | + + ### unproject **`unproject(win: array, model: array, proj: array, viewport: array)`** @@ -1802,6 +2826,33 @@ point is return. If it does not hit the mesh then obj is not set. |Returns| obj 3d unprojected mouse point in mesh
hits vector of hits
Returns number of hits | +### unproject_on_line +**`unproject_on_line(uv: array, m: array, vp: array, origin: array, dir: array)`** + +Given a screen space point (u,v) and the current projection matrix (e.g. +gl_proj * gl_modelview) and viewport, _unproject_ the point into the scene +so that it lies on given line (origin and dir) and projects as closely as +possible to the given screen space point. + +| | | +|-|-| +|Parameters| UV 2-long uv-coordinates of screen space point
M 4 by 4 projection matrix
VP 4-long viewport: (corner_u, corner_v, width, height)
origin point on line
dir vector parallel to line | +|Returns| t line parameter so that closest poin on line to viewer ray through UV
lies at origin+t*dir
Z 3d position of closest point on line to viewing ray through UV | + + +### unproject_on_plane +**`unproject_on_plane(uv: array, m: array, vp: array, p: array)`** + +Given a screen space point (u,v) and the current projection matrix (e.g. +gl_proj * gl_modelview) and viewport, _unproject_ the point into the scene +so that it lies on given plane. + +| | | +|-|-| +|Parameters| UV 2-long uv-coordinates of screen space point
M 4 by 4 projection matrix
VP 4-long viewport: (corner_u, corner_v, width, height)
P 4-long plane equation coefficients: P*(X 1) = 0 | +|Returns| Z 3-long world coordinate | + + ### unproject_onto_mesh **`unproject_onto_mesh(pos: array, model: array, proj: array, viewport: array, v: array, f: array)`** @@ -1888,6 +2939,60 @@ vertex_face_adjacency constructs the vertex-face topology of a given mesh (V,F) |Returns| VF 3*\#F list List of faces indice on each vertex, so that VF(NI(i)+j) =
f, means that face f is the jth face (in no particular order) incident
on vertex i.
NI \#V+1 list cumulative sum of vertex-triangle degrees with a
preceeding zero. "How many faces" have been seen before visiting this
vertex and its incident faces. | +### volume +**`volume(v: array, t: array)`** + +Computes volume for all tets of a given tet mesh (V,T) + +| | | +|-|-| +|Parameters| V \#V by dim list of vertex positions
T \#V by 4 list of tet indices | +|Returns| vol \#T list of dihedral angles (in radians) | + +**Examples** +```python +vol = volume(V,T) +``` + + +### volume_from_edges +**`volume_from_edges(l: array)`** + +Computes volume for all tets from edge lengths + +| | | +|-|-| +|Parameters| L \#V by 6 list of edge lengths (see edge_lengths) | +|Returns| vol volume of the tets | + + +### volume_from_vertices +**`volume_from_vertices(a: array, b: array, c: array, d: array)`** + +Compute volumes of a list of tets defined by a, b, c, d + +| | | +|-|-| +|Parameters| a,b,c,d list of vertices vertices of the tets | +|Returns| vol volume of the tets | + + +### volume_single +**`volume_single(a: array, b: array, c: array, d: array) -> float`** + +Volume of a single tet + +| | | +|-|-| +|Parameters| a,b,c,d vertices | +|Returns| volume | + +**Examples** +```python +Single tet +``` + + ### winding_number **`winding_number(v: array, f: array, o: array)`** @@ -1956,12 +3061,20 @@ write mesh to a file with automatic detection of file format. supported: obj, o ## class ARAP -**`solve(: igl.pyigl_classes.ARAP, arg0: numpy.ndarray, arg1: numpy.ndarray)`** +**`solve(: igl.pyigl_classes.ARAP, bc: numpy.ndarray, initial_guess: numpy.ndarray)`** + +## class BBW + +**`solve(: igl.pyigl_classes.BBW, V: numpy.ndarray, F: numpy.ndarray, b: numpy.ndarray[int32[m, 1]], bc: numpy.ndarray)`** ## class SLIM **`energy(: igl.pyigl_classes.SLIM) -> float`** -**`solve(: igl.pyigl_classes.SLIM, arg0: int)`** +**`solve(: igl.pyigl_classes.SLIM, num_iters: int)`** **`vertices(: igl.pyigl_classes.SLIM)`** + +## class shapeup + +**`solve(: igl.pyigl_classes.shapeup, bc: numpy.ndarray, P0: numpy.ndarray, local_projection: str = 'regular_face_projection', quietIterations: bool = True)`**