Skip to content

Commit 01eb87f

Browse files
Qingnan ZhouQingnan Zhou
authored andcommitted
Sync with 9c88af4
1 parent 05cce2e commit 01eb87f

8 files changed

Lines changed: 1223 additions & 250 deletions

File tree

‎docs/open/user/core/attributes.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Mesh Attributes
22

33
!!! warning "Legacy Mesh vs Surface Mesh"
4-
Since v6.0.0, Lagrange introduced a new polygonal mesh class that is meant to replace the
5-
original mesh class used throughout Lagrange. While currently few of the Lagrange functions use
6-
this new mesh class, over time old and new features will transition to use this new data
7-
structure.
4+
Since v6.0.0, Lagrange provides a polygonal mesh class ([SurfaceMesh](mesh.md)) that replaces the
5+
original (legacy) mesh class. It is now the default mesh type used throughout Lagrange. The
6+
legacy mesh class remains available only as an opt-in, via the `LAGRANGE_ENABLE_LEGACY_FUNCTIONS`
7+
option.
88

99
<!-- @header
1010
#include <lagrange/SurfaceMesh.h>
@@ -91,12 +91,12 @@ auto id0 = mesh.create_attribute<double>(
9191
"color",
9292
lagrange::AttributeElement::Corner);
9393

94-
// Optionally specify usage tag + num channels.
94+
// Optionally specify num channels + usage tag.
9595
auto id1 = mesh.create_attribute<float>(
9696
"normals",
9797
lagrange::AttributeElement::Vertex,
98-
lagrange::AttributeUsage::Normal,
99-
3);
98+
3,
99+
lagrange::AttributeUsage::Normal);
100100

101101
// View attribute as a Eigen::Map<const ...>
102102
auto attr_matrix = matrix_view(mesh.get_attribute<float>(id1));
@@ -151,7 +151,7 @@ lagrange::SurfaceMesh<Scalar, Index> mesh;
151151

152152
// ...
153153

154-
// Returns a const Attribute<T> &
154+
// Returns a const IndexedAttribute<T, Index> &
155155
const auto& attr = mesh.get_indexed_attribute<Scalar>("normals");
156156

157157
const auto& attr_indices = attr.indices();

‎docs/open/user/core/general-utilities.md‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct
3232
{
3333
std::string log_file;
3434
int log_level = 2;
35+
bool quiet = false;
3536
} args;
3637
3738
// Parse command-line args with CLI11
@@ -125,14 +126,14 @@ type1 x = lagrange::safe_cast<type1>(y);
125126

126127
## Pointer Type Conversion
127128

128-
It often necessary to convert a `std::unique_ptr` to `std::shared_ptr`.
129-
Lagrange provide a handy function that avoid repeated type specification:
129+
It is often necessary to convert a `std::unique_ptr` to `std::shared_ptr`.
130+
Lagrange provides a handy function that avoids repeated type specification:
130131

131132
```c++
132133
#include <lagrange/common.h>
133134

134135
std::unique_ptr<T> unique_val = ...;
135-
auto shared_val = lagrange::to_shared_ptr(unique_val);
136+
auto shared_val = lagrange::to_shared_ptr(std::move(unique_val));
136137
assert(unique_val == nullptr);
137138
assert(shared_val.use_count() == 1);
138139
```
@@ -196,8 +197,6 @@ std::vector<Edge> min_spanning_tree(
196197

197198
// Iterate over all input edges in ascending order
198199
for (auto [x, y] : sorted_edges) {
199-
[x, y] = sorted_edges[e];
200-
201200
// If vertices belong to disconnected unrooted trees,
202201
// merge them and add edge (x, y) to the solution
203202
if (union_find.find(x) != union_find.find(y)) {
@@ -255,13 +254,13 @@ currently supports Linux and macOS. On non-supported platform, calling the funct
255254

256255
void my_main() {
257256
lagrange::enable_fpe();
258-
// call problematic operation []...]
257+
// call problematic operation [...]
259258
lagrange::disable_fpe();
260259
}
261260
```
262261

263262
!!! tip "Compilation Issues"
264-
If our implementation of `enable_fpe()` casues compilation issues on your target platform (e.g.
263+
If our implementation of `enable_fpe()` causes compilation issues on your target platform (e.g.
265264
macOS M1, Emscripten, etc.), it is possible to disable the feature explicitly by setting the
266265
CMake option `LAGRANGE_DISABLE_FPE=ON`. In this case, calling `enable_fpe()` will do nothing.
267266

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
<!-- $ignore -->
2+
3+
# Legacy Mesh Cleanup
4+
5+
!!! warning "Legacy Mesh"
6+
Documentation on this page relies on our [legacy mesh](legacy-mesh.md) data
7+
structure. For the current `SurfaceMesh`-based cleanup utilities, see the
8+
[Mesh Cleanup](mesh-cleanup.md) page.
9+
10+
Lagrange supports a number of mesh cleanup operations. Typically, a mesh
11+
cleanup operation takes a mesh object as input and creates a new [Mesh] object.
12+
For example, all mesh cleanup functions have the same function signature:
13+
14+
```c++
15+
auto out_mesh_unique = lagrange::function_name(in_mesh);
16+
```
17+
18+
Therefore, it is possible to combine mesh cleanup operations by chaining them.
19+
Existing vertex/facet/corner attributes can be seamlessly ported from the input
20+
mesh to the output mesh.
21+
22+
!!! warning "Limitation"
23+
Edge attribute is not ported at the moment.
24+
25+
## Remove Isolated Vertices
26+
27+
An isolated vertex is a vertex that is not adjacent to any facet. It can be
28+
removed with `remove_isolated_vertices` function:
29+
30+
```c++
31+
#include <lagrange/mesh_cleanup/remove_isolated_vertices.h>
32+
auto mesh2_unique = lagrange::remove_isolated_vertices(
33+
mesh);
34+
```
35+
36+
## Remove Duplicate Vertices
37+
38+
Two vertices are considered duplicates if they have _exactly_ the same
39+
coordinates. To remove duplicate vertices:
40+
41+
```c++
42+
#include <lagrange/mesh_cleanup/remove_duplicate_vertices.h>
43+
auto mesh_unique = lagrange::remove_duplicate_vertices(
44+
mesh);
45+
```
46+
47+
It is also possible to add an extra condition when checking for vertex
48+
duplicates. By specifying a vertex attribute, two vertices are considered
49+
duplicates if they have _exactly_ the same coordinates and attribute values.
50+
For example:
51+
52+
```c++
53+
#include <lagrange/mesh_cleanup/remove_duplicate_vertices.h>
54+
auto mesh2_unique = lagrange::remove_duplicate_vertices(
55+
mesh, "color");
56+
```
57+
58+
This call will remove all duplicate vertices that have the same coordinates and
59+
color as defined by the "color" vertex attribute.
60+
61+
## Remove Degenerate Triangles
62+
63+
A triangle is called degenerate if all of its vertices are _exactly_ collinear.
64+
Lagrange relies on exact predicates to check collinearity.
65+
66+
```c++
67+
#include <lagrange/mesh_cleanup/remove_degenerate_triangles.h>
68+
auto mesh2_unique = lagrange::remove_degenerate_triangles(
69+
mesh);
70+
```
71+
72+
## Remove Topologically Degenerate Triangles
73+
74+
A triangle is called _topologically_ degenerate if two or more of its vertices
75+
are the same topologically. For example, a triangle `[1, 1, 2]` is
76+
topologically degenerate because two of its vertices are referring to the same
77+
vertex (the vertex with index `1`). Topological degeneracy is a special case of
78+
general degeneracy and it is possible to identify it from connectivity alone.
79+
80+
```c++
81+
#include <lagrange/mesh_cleanup/remove_topologically_degenerate_triangles.h>
82+
auto mesh2_unique = lagrange::remove_topologically_degenerate_triangles(
83+
mesh);
84+
```
85+
86+
## Remove Short Edges
87+
88+
To remove all edges shorter than a given threshold:
89+
90+
```c++
91+
#include <lagrange/mesh_cleanup/remove_short_edges.h>
92+
auto mesh2_unique = lagrange::remove_short_edges(
93+
mesh, tol);
94+
```
95+
96+
where `tol` is the target edge length threshold.
97+
98+
99+
## Remove Duplicate Facets
100+
101+
Two facets are considered duplicates of each other if they are formed by the
102+
same combination of vertices. E.g. facet `[1, 2, 3]` is considered as duplicate of
103+
facet `[3, 2, 1]`. To remove all duplicate facets:
104+
105+
```c++
106+
#include <lagrange/mesh_cleanup/remove_duplicate_facets.h>
107+
auto mesh2_unique = lagrange::remove_duplicate_facets(
108+
mesh);
109+
```
110+
111+
!!! note
112+
Facet orientation is not considered. Even though facet `[1, 2, 3]`
113+
and `[3, 2, 1]` have opposite orientations, they are considered as duplicates.
114+
115+
## Split Long Edges
116+
117+
It is often that we need to refine a triangular mesh by splitting long edges:
118+
119+
```c++
120+
#include <lagrange/mesh_cleanup/split_long_edges.h>
121+
auto mesh2_unique = lagrange::split_long_edges(
122+
mesh, sq_tol, true);
123+
```
124+
125+
Other than the input mesh, `lagrange::split_long_edges` takes two more
126+
parameters:
127+
128+
* `sq_tol`: The target edge length squared. All edges longer than this
129+
threshold will be split.
130+
* `recursive`: Whether to split _recursively_. Because edge splitting will
131+
introduce new edges and these new edges may be longer than the specified
132+
threshold. Splitting recursively will guarantee the output mesh contain no
133+
edge longer than the specified threshold.
134+
135+
!!! note
136+
Only _long_ edges are split. This is different from uniform
137+
refinement where all edges are split.
138+
139+
## Resolve Nonmanifoldness
140+
141+
Lagrange can convert a [nonmanifold mesh] to a [manifold mesh]:
142+
143+
```c++
144+
#include <lagrange/mesh_cleanup/resolve_nonmanifoldness.h>
145+
auto mesh2_unique = lagrange::resolve_nonmanifoldness(
146+
mesh);
147+
```
148+
149+
where nonmanifold vertices and edges are "pulled apart".
150+
151+
!!! example "Implementation details"
152+
Here is an illustration describing how Lagrange
153+
"pulls apart" nonmanifold vertices and edges:
154+
155+
![Nonmanifold cases](img/nonmanifold_cases.png)
156+
157+
158+
[nonmanifold mesh]: legacy-mesh.md#topology
159+
[manifold mesh]: legacy-mesh.md#topology
160+
161+
## Convert Quad Mesh To Triangular Mesh
162+
163+
Lagrange also provides handy function to convert a quad to a triangular mesh:
164+
165+
```c++
166+
#include <lagrange/quad_to_tri.h>
167+
auto mesh2_unique = lagrange::quad_to_tri(mesh);
168+
```
169+
170+
!!! example "Implementation details"
171+
Each quad is converted to 2 triangles by inserting
172+
one of its diagonals procedurally.
173+
174+
## Submesh Extraction
175+
176+
It is often necessary to extract a subset of the facets from a given mesh. Such
177+
operation is supported via `lagrange::extract_submesh` function:
178+
179+
```c++
180+
#include <lagrange/extract_submesh.h>
181+
182+
std::vector<int> selected_facets;
183+
// Populate selected_facets with facet indices.
184+
185+
auto submesh_unique = lagrange::extract_submesh(
186+
mesh, selected_facets);
187+
```
188+
189+
[Mesh]: legacy-mesh.md

0 commit comments

Comments
 (0)