Wildmeshing Toolkit
Loading...
Searching...
No Matches
IsotropicRemeshing.h
1#pragma once
2
3#include <wmtk/utils/PartitionMesh.h>
4#include <wmtk/utils/VectorUtils.h>
5#include <wmtk/envelope/BoundaryEnvelope.hpp>
6#include <wmtk/envelope/Envelope.hpp>
7#include "wmtk/AttributeCollection.hpp"
8
9// clang-format off
10#include <wmtk/utils/DisableWarnings.hpp>
11#include <igl/write_triangle_mesh.h>
12#include <wmtk/threading/enumerable_thread_specific.hpp>
13#include <fastenvelope/FastEnvelope.h>
14#include <wmtk/utils/EnableWarnings.hpp>
15// clang-format on
16
17#include <Eigen/Core>
18#include <Eigen/Geometry>
19#include <atomic>
20#include <memory>
21#include <optional>
22#include <queue>
23
24namespace wmtk::components::isotropic_remeshing {
25
27{
28 Eigen::Vector3d pos;
29 // TODO: in fact, partition id should not be vertex attribute, it is a fixed marker to distinguish tuple/operations.
30 size_t partition_id;
31 bool freeze = false;
36 bool input_boundary = false;
37};
38
41{
42 std::vector<size_t> nbrs;
44 std::vector<int64_t> ids;
46 bool fixed = false;
48 int64_t vertex_id = -1;
49};
50
54{
55 std::vector<double> values;
56 int64_t region = -1;
57};
58
62{
64 std::vector<std::pair<int64_t, Eigen::Vector3d>> normals;
66 size_t against = 0;
69 size_t star_folds = 0;
73 struct Crease
74 {
75 size_t a = 0, b = 0;
76 int orientation = 0;
77 };
78 std::vector<Crease> creases;
80 std::optional<Eigen::Vector3d> normal(int64_t region) const
81 {
82 for (const auto& [r, n] : normals) {
83 if (r == region) return n;
84 }
85 return std::nullopt;
86 }
88 const Crease* crease(size_t a, size_t b) const
89 {
90 for (const Crease& c : creases) {
91 if ((c.a == a && c.b == b) || (c.a == b && c.b == a)) return &c;
92 }
93 return nullptr;
94 }
97 void rename(size_t from, size_t to)
98 {
99 for (Crease& c : creases) {
100 if (c.a == from) c.a = to;
101 if (c.b == from) c.b = to;
102 }
103 }
105 bool folded() const { return against > 0 || star_folds > 0; }
106};
107
109{
110public:
111 wmtk::Envelope m_envelope;
112 bool m_has_envelope = false;
119
121 VertAttCol vertex_attrs;
127
151 void set_feature_edges(const std::vector<std::array<size_t, 2>>& edges);
159 const std::vector<std::array<size_t, 2>>& edges,
160 const std::vector<int64_t>& ids);
162 std::vector<std::array<size_t, 2>> feature_edges() const;
163 bool is_feature_edge(size_t a, size_t b) const;
165 int64_t feature_edge_id(size_t a, size_t b) const;
166 size_t feature_degree(size_t v) const;
167
175 void set_fixed_vertices(const std::vector<std::pair<size_t, int64_t>>& vertices);
176 bool is_fixed(size_t v) const { return m_has_fixed && feature_attrs.at(v).fixed; }
184 bool stays_put(size_t v) const;
193 bool may_collapse_away(const Tuple& t) const;
194
203 void set_face_fields(const std::vector<std::vector<double>>& values);
204 bool has_face_fields() const { return m_has_face_fields; }
205
220 void set_feature_envelope(double eps);
222 void consolidate_mesh();
238 size_t remove_feature_ears();
240 bool is_feature_ear_tip(const Tuple& v) const;
241
279 void set_check_inversions(bool check) { m_check_inversions = check; }
289 void set_swap_quality(bool quality) { m_swap_quality = quality; }
297 void set_limit_collapse_length(bool limit) { m_limit_collapse_length = limit; }
309 void set_cleanup_angle(double degrees) { m_cleanup_angle = degrees; }
333 size_t cleanup_triangles(double degrees);
335 size_t refused_inversions() const { return m_refused_inversions; }
342 bool smooth_vertex_to(size_t v, const Eigen::Vector3d& p);
343
344 int retry_limit = 10;
346 std::vector<Eigen::Vector3d> _m_vertex_positions,
347 int num_threads = 1,
348 bool use_exact = true);
349
351
371 void create_mesh(
372 size_t n_vertices,
373 const std::vector<std::array<size_t, 3>>& tris,
374 const std::vector<size_t>& frozen_verts = std::vector<size_t>(),
375 bool m_freeze = true,
376 double eps = 0,
377 double boundary_eps = 0);
378
380 {
381 Eigen::Vector3d v1p;
382 Eigen::Vector3d v2p;
383 size_t partition_id;
384 // Collapse: of t.vid() (v1) and of the other endpoint (v2). All false without a
385 // boundary envelope, where no vertex is flagged.
386 bool v1_input_boundary = false;
387 bool v2_input_boundary = false;
388 // An input_boundary vertex that is still on the boundary.
389 bool v1_on_boundary = false;
390 bool v2_on_boundary = false;
391 // Split: the new vertex lands on a boundary edge that touches an input_boundary vertex.
392 bool split_input_boundary = false;
393 // Feature curves: the edge's endpoints (t.vid() first), whether it is a feature edge and
394 // its id, and whether a collapse leaves the survivor where it is.
395 size_t v1 = 0, v2 = 0;
396 bool feature_edge = false;
397 int64_t feature_id = -1;
398 bool keep_v2_position = false;
399 // Collapse and swap, checking inversions: what the operation replaces.
400 ReplacedSurface replaced;
401 // A split is under way: its invariants skip the feature envelope.
402 bool splitting = false;
403 // Collapse and swap, in cleanup_triangles(): where what the operation replaces folds
404 // already, its triangles that face against the input; 0 elsewhere, where it is not read.
405 size_t input_folds = 0;
406 };
408
409 void cache_edge_positions(const Tuple& t);
410
411 bool invariants(const std::vector<Tuple>& new_tris) override;
412
413 // TODO: this should not be here
414 void partition_mesh();
415
416 // TODO: morton should not be here, but inside wmtk
417 void partition_mesh_morton();
418
419 size_t get_partition_id(const Tuple& loc) const
420 {
421 return vertex_attrs[loc.vid(*this)].partition_id;
422 }
423
424 bool smooth_all_vertices();
425
426 Eigen::Vector3d smooth(const Tuple& t);
427
428
429 Eigen::Vector3d tangential_smooth(const Tuple& t);
430
431 bool collapse_edge_before(const Tuple& t) override;
432 bool collapse_edge_after(const Tuple& t) override;
433
434 bool swap_edge_before(const Tuple& t) override;
435 bool swap_edge_after(const Tuple& t) override;
436
437 std::vector<TriMesh::Tuple> new_edges_after(const std::vector<TriMesh::Tuple>& tris) const;
438 std::vector<TriMesh::Tuple> new_edges_after_swap(const TriMesh::Tuple& t) const;
439 std::vector<TriMesh::Tuple> replace_edges_after_split(
440 const std::vector<TriMesh::Tuple>& tris,
441 const size_t vid_threshold) const;
442 std::vector<TriMesh::Tuple> new_sub_edges_after_split(
443 const std::vector<TriMesh::Tuple>& tris) const;
444
445
446 bool split_edge_before(const Tuple& t) override;
447 bool split_edge_after(const Tuple& t) override;
448
449 bool smooth_before(const Tuple& t) override;
450 bool smooth_after(const Tuple& t) override;
451
452 double compute_edge_cost_collapse(const TriMesh::Tuple& t, double L) const;
453 double compute_edge_cost_split(const TriMesh::Tuple& t, double L) const;
454 double compute_vertex_valence(const TriMesh::Tuple& t) const;
458 double compute_swap_quality(const TriMesh::Tuple& t) const;
470 std::vector<double> average_len_valen();
471 bool split_remeshing(double L);
472 bool collapse_remeshing(double L);
473 bool swap_remeshing();
474 bool uniform_remeshing(double L, int interations);
475 bool write_triangle_mesh(std::string path);
476
477private:
478 wmtk::AttributeContainerGroup m_vertex_group;
479 bool m_has_features = false;
480 bool m_has_fixed = false;
482 bool m_has_edge_ids = false;
483 bool m_has_face_fields = false;
484 bool m_has_feature_envelope = false;
486 bool m_removing_ears = false;
487 bool m_check_inversions = true;
488 bool m_swap_quality = false;
489 bool m_limit_collapse_length = false;
490 double m_cleanup_angle = 0;
493 double m_cleanup_floor = 0;
494 bool m_cleaning = false;
496 std::optional<Eigen::Vector3d> m_smooth_target;
498 double m_envelope_eps = 0;
499 std::vector<Eigen::Vector3d> m_input_area;
500 std::vector<std::vector<double>> m_input_values;
503 std::atomic<size_t> m_refused_inversions = 0;
504
506 bool m_has_regions = false;
509 void set_regions();
511 int64_t region(const Tuple& f) const;
513 std::vector<std::pair<int64_t, std::vector<Tuple>>> by_region(
514 const std::vector<Tuple>& tris) const;
517 template <typename F>
518 void for_each_region(const std::vector<Tuple>& tris, F&& side) const;
523 std::vector<std::array<size_t, 6>> feature_wedges(const std::vector<Tuple>& tris) const;
526 bool closes_a_crease(const std::vector<Tuple>& tris, const ReplacedSurface& before) const;
528 Eigen::Vector3d area_normal(const std::vector<Tuple>& tris) const;
530 size_t not_facing(const std::vector<Tuple>& tris, const Eigen::Vector3d& n) const;
535 size_t star_folds(const std::vector<Tuple>& tris) const;
537 ReplacedSurface replaced(const std::vector<Tuple>& tris) const;
540 bool more_folds(const std::vector<Tuple>& tris, const ReplacedSurface& before) const;
542 bool folds(const std::vector<Tuple>& tris, const ReplacedSurface& before);
543
545 double min_angle(const std::vector<Tuple>& tris) const;
547 Eigen::Vector3d input_normal(const Tuple& f) const;
549 size_t input_folds(const std::vector<Tuple>& tris) const;
553 bool cleanup_allows(
554 const std::vector<Tuple>& tris,
555 const ReplacedSurface& before,
556 size_t input_folds_before,
557 double floor) const;
559 bool cleanup_move(size_t v, double floor);
560};
561
562} // namespace wmtk::components::isotropic_remeshing
Several attribute collections for the same simplex type, behind one container.
Definition AttributeCollection.hpp:143
A tube around the open boundary of a triangle mesh, for operations allowed to move it.
Definition BoundaryEnvelope.hpp:43
Definition Envelope.hpp:19
Definition TriMesh.h:36
size_t vid(const TriMesh &) const
Definition TriMesh.h:76
Definition TriMesh.h:32
bool collapse_edge_after(const Tuple &t) override
User specified modifications and desideratas after an edge collapse.
Definition IsotropicRemeshing.cpp:998
bool invariants(const std::vector< Tuple > &new_tris) override
User specified invariants that can't be violated.
Definition IsotropicRemeshing.cpp:730
bool split_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge split.
Definition IsotropicRemeshing.cpp:1061
void set_cleanup_angle(double degrees)
Repair, at the end of every iteration, the triangles whose smallest angle is under degrees; 0,...
Definition IsotropicRemeshing.h:309
bool is_feature_ear_tip(const Tuple &v) const
Whether v is on a curve and one triangle holds both of its curve edges.
Definition IsotropicRemeshing.cpp:1159
bool m_has_edge_ids
Some feature edge has an id other than -1.
Definition IsotropicRemeshing.h:482
wmtk::AttributeCollection< FaceFieldAttributes > face_field_attrs
Definition IsotropicRemeshing.h:126
bool collapse_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge collapse including the link check as collapse...
Definition IsotropicRemeshing.cpp:912
void set_feature_envelope(double eps)
Keep the curves near the feature edges as they are now – the input's, called before remeshing: every ...
Definition IsotropicRemeshing.cpp:774
std::vector< std::pair< int64_t, std::vector< Tuple > > > by_region(const std::vector< Tuple > &tris) const
The triangles, by region (see set_feature_edges), in the order the regions first appear.
Definition IsotropicRemeshing.cpp:182
ReplacedSurface replaced(const std::vector< Tuple > &tris) const
The triangles an operation is about to replace.
Definition IsotropicRemeshing.cpp:264
bool swap_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge swap including 1.can't swap on boundary edge....
Definition IsotropicRemeshing.cpp:831
void for_each_region(const std::vector< Tuple > &tris, F &&side) const
Definition IsotropicRemeshing.cpp:203
void create_mesh(size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris, const std::vector< size_t > &frozen_verts=std::vector< size_t >(), bool m_freeze=true, double eps=0, double boundary_eps=0)
Definition IsotropicRemeshing.cpp:52
void set_regions()
Definition IsotropicRemeshing.cpp:599
int64_t feature_edge_id(size_t a, size_t b) const
The id set_feature_edges gave the feature edge (a, b): -1 for none, or for no feature edge.
Definition IsotropicRemeshing.cpp:681
bool stays_put(size_t v) const
Whether v is never moved and never removed: a curve's end, a junction of curves, a vertex between fea...
Definition IsotropicRemeshing.cpp:694
bool cleanup_move(size_t v, double floor)
Moves v to where the smallest angle of its star is largest, above floor.
Definition IsotropicRemeshing.cpp:424
std::vector< double > average_len_valen()
Report statistics.
Definition IsotropicRemeshing.cpp:1327
Eigen::Vector3d input_normal(const Tuple &f) const
The area vectors of the input triangles next to f, summed: see cleanup_triangles().
Definition IsotropicRemeshing.cpp:366
bool folds(const std::vector< Tuple > &tris, const ReplacedSurface &before)
The same; counts a refusal.
Definition IsotropicRemeshing.cpp:339
double m_collapse_target
The target length of the last collapse_remeshing(), for the limit above.
Definition IsotropicRemeshing.h:502
Eigen::Vector3d area_normal(const std::vector< Tuple > &tris) const
The area vectors of the triangles, summed (twice over).
Definition IsotropicRemeshing.cpp:153
bool closes_a_crease(const std::vector< Tuple > &tris, const ReplacedSurface &before) const
Definition IsotropicRemeshing.cpp:307
bool smooth_vertex_to(size_t v, const Eigen::Vector3d &p)
Moves v to p as a smoothing: smooth_vertex() with p in place of the smoothed position,...
Definition IsotropicRemeshing.cpp:476
bool more_folds(const std::vector< Tuple > &tris, const ReplacedSurface &before) const
Definition IsotropicRemeshing.cpp:323
void set_face_fields(const std::vector< std::vector< double > > &values)
Per-face values the remeshing carries: per-face labels, say, whose boundaries are feature edges....
Definition IsotropicRemeshing.cpp:644
std::vector< std::array< size_t, 6 > > feature_wedges(const std::vector< Tuple > &tris) const
Definition IsotropicRemeshing.cpp:212
wmtk::BoundaryEnvelope m_boundary_envelope
Definition IsotropicRemeshing.h:116
double m_envelope_eps
With a cleanup angle: the envelope's eps, and the input's area vectors and face fields.
Definition IsotropicRemeshing.h:498
void set_fixed_vertices(const std::vector< std::pair< size_t, int64_t > > &vertices)
Vertices the remeshing keeps exactly: B-rep corners, say, which may sit inside a curve between two re...
Definition IsotropicRemeshing.cpp:630
bool smooth_after(const Tuple &t) override
User specified modifications and desideras after an edge smooth.
Definition IsotropicRemeshing.cpp:1136
bool may_collapse_away(const Tuple &t) const
Whether the curve rules let a collapse of t remove t.vid(): it does not stay put, and if it is on a c...
Definition IsotropicRemeshing.cpp:703
wmtk::Envelope m_feature_envelope
Around the feature edges set_feature_envelope() saw; initialized() is false without one.
Definition IsotropicRemeshing.h:118
bool m_has_regions
The faces have their regions (see set_feature_edges).
Definition IsotropicRemeshing.h:506
bool smooth_before(const Tuple &t) override
User specified preparations and desideratas for an edge smooth.
Definition IsotropicRemeshing.cpp:1124
void set_feature_edges(const std::vector< std::array< size_t, 2 > > &edges)
Curves the remeshing keeps: label boundaries, say.
Definition IsotropicRemeshing.cpp:565
size_t remove_feature_ears()
Removes the triangles that hold two feature edges – "ears".
Definition IsotropicRemeshing.cpp:1173
size_t refused_inversions() const
The operations set_check_inversions() refused, since the mesh was made.
Definition IsotropicRemeshing.h:335
std::vector< std::array< size_t, 2 > > feature_edges() const
The feature edges, smaller vertex id first.
Definition IsotropicRemeshing.cpp:660
size_t cleanup_triangles(double degrees)
Repairs the triangles whose smallest angle is under degrees, worst first.
Definition IsotropicRemeshing.cpp:484
double m_cleanup_floor
Definition IsotropicRemeshing.h:493
bool cleanup_allows(const std::vector< Tuple > &tris, const ReplacedSurface &before, size_t input_folds_before, double floor) const
Definition IsotropicRemeshing.cpp:410
bool swap_edge_after(const Tuple &t) override
User specified modifications and desideras after an edge swap.
Definition IsotropicRemeshing.cpp:861
void set_check_inversions(bool check)
Refuse a collapse, swap or smoothing that folds the surface over.
Definition IsotropicRemeshing.h:279
size_t not_facing(const std::vector< Tuple > &tris, const Eigen::Vector3d &n) const
How many of the triangles do not face along n.
Definition IsotropicRemeshing.cpp:164
void set_swap_quality(bool quality)
Swap an edge to raise the worse shape quality of its two triangles (see compute_swap_quality),...
Definition IsotropicRemeshing.h:289
void consolidate_mesh()
TriMesh::consolidate_mesh, plus the renumbering of the feature edges.
Definition IsotropicRemeshing.cpp:711
size_t input_folds(const std::vector< Tuple > &tris) const
How many of the triangles do not face along input_normal().
Definition IsotropicRemeshing.cpp:397
int64_t region(const Tuple &f) const
The region of the curves f lies in; -1 without curves.
Definition IsotropicRemeshing.cpp:176
double compute_swap_quality(const TriMesh::Tuple &t) const
Definition IsotropicRemeshing.cpp:1269
double min_angle(const std::vector< Tuple > &tris) const
The smallest angle of the triangles, in degrees.
Definition IsotropicRemeshing.cpp:346
bool m_removing_ears
Set while remove_feature_ears() runs (serially): its collapses may make an ear.
Definition IsotropicRemeshing.h:486
bool split_edge_after(const Tuple &t) override
User specified modifications and desideratas after an edge split.
Definition IsotropicRemeshing.cpp:1078
std::optional< Eigen::Vector3d > m_smooth_target
Where cleanup_triangles() moves a vertex, in place of the smoothing's position.
Definition IsotropicRemeshing.h:496
void set_limit_collapse_length(bool limit)
Refuse a collapse that leaves an edge longer than 4/3 of the target length – the split threshold – as...
Definition IsotropicRemeshing.h:297
wmtk::AttributeCollection< FeatureAttributes > feature_attrs
Read and written only while the mesh has feature edges or fixed vertices.
Definition IsotropicRemeshing.h:123
size_t star_folds(const std::vector< Tuple > &tris) const
Definition IsotropicRemeshing.cpp:244
Definition enumerable_thread_specific.hpp:37
A vertex's neighbours across feature edges (see IsotropicRemeshing::set_feature_edges).
Definition IsotropicRemeshing.h:41
bool fixed
Set by IsotropicRemeshing::set_fixed_vertices: never moved, never removed.
Definition IsotropicRemeshing.h:46
int64_t vertex_id
The id set_fixed_vertices gave it; -1 for none.
Definition IsotropicRemeshing.h:48
std::vector< int64_t > ids
The id of the feature edge to each of nbrs, in the same order; -1 for none.
Definition IsotropicRemeshing.h:44
size_t against
The ones that do not face along their region's normal.
Definition IsotropicRemeshing.h:66
size_t star_folds
Definition IsotropicRemeshing.h:69
std::optional< Eigen::Vector3d > normal(int64_t region) const
The summed area vectors of region; none if the triangles have none there.
Definition IsotropicRemeshing.h:80
std::vector< std::pair< int64_t, Eigen::Vector3d > > normals
Each region's area vectors, summed.
Definition IsotropicRemeshing.h:64
const Crease * crease(size_t a, size_t b) const
The crease (a, b), in either order; none if the triangles have no such crease.
Definition IsotropicRemeshing.h:88
void rename(size_t from, size_t to)
Definition IsotropicRemeshing.h:97
bool folded() const
Whether they, or the stars around them, fold the surface over already.
Definition IsotropicRemeshing.h:105
bool input_boundary
Definition IsotropicRemeshing.h:36