Wildmeshing Toolkit
Loading...
Searching...
No Matches
SimWildMeshTri.hpp
1#pragma once
2
3#include <limits>
4#include <unordered_set>
5
6#include <wmtk/utils/PartitionMesh.h>
7#include <wmtk/utils/VectorUtils.h>
8#include <polysolve/nonlinear/Problem.hpp>
9#include <wmtk/AttributeCollection.hpp>
10#include <wmtk/Types.hpp>
11#include <wmtk/envelope/Envelope.hpp>
12#include <wmtk/optimization/solver.hpp>
13
14// clang-format off
15#include <wmtk/utils/DisableWarnings.hpp>
16#include <igl/write_triangle_mesh.h>
17#include <tbb/concurrent_priority_queue.h>
18#include <tbb/concurrent_vector.h>
19#include <tbb/enumerable_thread_specific.h>
20#include <tbb/parallel_for.h>
21#include <tbb/parallel_sort.h>
22#include <fastenvelope/FastEnvelope.h>
23#include <wmtk/utils/EnableWarnings.hpp>
24// clang-format on
25
26#include "ConnectedComponent.hpp"
27#include "Parameters.h"
28#include "expression_parser/Expression.hpp"
29
30
31namespace wmtk::components::simwild::tri {
32
34{
35 Vector2d m_pos;
36 bool m_is_on_surface = false;
37 std::vector<int> on_bbox_faces;
38
39 double m_sizing_scalar = 1;
40
41 size_t partition_id = 0;
42
44 VertexAttributes(const Vector2d& p)
45 : m_pos(p)
46 {}
47};
48
50{
51public:
52 double tag; // TODO: is this used?
53
54 bool m_is_surface_fs = false; // 0; 1
64 int m_is_bbox_fs = -1; //-1; 0~5
65
66 void reset()
67 {
68 m_is_surface_fs = false;
69 m_is_bbox_fs = -1;
70 }
71
72 void merge(const EdgeAttributes& attr)
73 {
74 m_is_surface_fs = m_is_surface_fs || attr.m_is_surface_fs;
75 if (attr.m_is_bbox_fs >= 0) m_is_bbox_fs = attr.m_is_bbox_fs;
76 }
77};
78
80{
81public:
82 double m_quality;
83 double m_winding_number = 0;
84 CellTag tags;
85 int part_id = -1;
86};
87
89{
90public:
91 using ExprPtr = expression_parser::ExpressionPtr;
92
93 int m_debug_print_counter = 0;
94 size_t m_tags_count = 0;
95 std::map<int64_t, std::string> m_tag_id_to_name;
96 std::map<std::string, int64_t> m_tag_name_to_id;
97
98 const double MAX_ENERGY = std::numeric_limits<double>::max();
99
100 Parameters& m_params;
101 std::vector<Vector2d> m_V_envelope;
102 std::vector<Vector2i> m_E_envelope;
103 std::shared_ptr<SampleEnvelope> m_envelope;
104 std::shared_ptr<SampleEnvelope> m_envelope_orig;
105 double m_envelope_eps = -1;
106
107 using VertAttCol = AttributeCollection<VertexAttributes>;
108 using EdgeAttCol = AttributeCollection<EdgeAttributes>;
109 using FaceAttCol = AttributeCollection<FaceAttributes>;
110 VertAttCol m_vertex_attribute;
111 EdgeAttCol m_edge_attribute;
112 FaceAttCol m_face_attribute;
113
114 bool m_collapse_check_link_condition = false; // classical link condition
115 bool m_collapse_check_topology = false; // sanity check
116 bool m_collapse_check_manifold = false; // manifoldness check after collapse
117
118 tbb::enumerable_thread_specific<std::unique_ptr<polysolve::nonlinear::Solver>> m_solver;
119
120 // scaling factors
121 double m_s_amips = -1;
122 double m_s_envelope = -1;
123
124 SimWildMeshTri(Parameters& _m_params, double envelope_eps, int _num_threads = 0)
125 : m_params(_m_params)
126 , m_envelope_eps(envelope_eps)
127 {
128 NUM_THREADS = _num_threads;
129 p_vertex_attrs = &m_vertex_attribute;
130 p_edge_attrs = &m_edge_attribute;
131 p_face_attrs = &m_face_attribute;
132
133 optimization::deactivate_opt_logger();
134
135 m_s_amips = 1.;
140 m_s_envelope = 1. / (m_params.eps * m_params.eps);
141
142
143 double& wa = m_params.w_amips;
144 double& we = m_params.w_envelope;
145 we = 1 - wa;
146 logger().info("w_envelope = {}", we);
147 }
148
149 ~SimWildMeshTri() {}
150
151 // TODO: this should not be here
152 void partition_mesh();
153
154 // TODO: morton should not be here, but inside wmtk
155 void partition_mesh_morton();
156
157 size_t get_partition_id(const Tuple& loc) const
158 {
159 return m_vertex_attribute[loc.vid(*this)].partition_id;
160 }
161
162 double get_length2(const Tuple& l) const;
163
164
165public:
175 void init_from_image(
176 const MatrixXd& V,
177 const MatrixXi& T,
178 const MatrixSi& T_tags,
179 const std::vector<std::string>& tag_names);
180
181 void init_surfaces_and_boundaries();
182
183 void init_envelope(const MatrixXd& V, const MatrixXi& F);
184
185 CellTag string_set_to_cell_tag(const std::set<std::string>& str_set);
186
187 bool adjust_sizing_field_serial(double max_energy);
188
189 void write_msh(std::string file, const bool write_envelope = true);
190
191 void write_vtu(const std::string& path) const;
192 void write_vtu_with_energies(const std::string& path) const;
193
194 std::vector<std::array<size_t, 2>> get_edges_by_condition(
195 std::function<bool(const EdgeAttributes&)> cond) const;
196
197public:
198 void split_all_edges();
199 bool split_edge_before(const Tuple& t) override;
200 bool split_edge_after(const Tuple& loc) override;
201
202 void collapse_all_edges(bool is_limit_length = true);
203 bool collapse_edge_before(const Tuple& t) override;
204 bool collapse_edge_after(const Tuple& t) override;
205
206 size_t swap_all_edges();
212 double swap_weight(const Tuple& t) const;
213 bool swap_edge_before(const Tuple& t) override;
214 bool swap_edge_after(const Tuple& t) override;
215
216 void smooth_all_vertices(const size_t n_iters = 1);
217 bool smooth_before(const Tuple& t) override;
218 bool smooth_after(const Tuple& t) override;
219
225 std::vector<Vector2d> get_surface_assembles(const Tuple& t) const;
226 std::shared_ptr<polysolve::nonlinear::Problem> get_envelope_energy(const Tuple& t) const;
227
228 std::vector<std::array<double, 6>> get_amips_assembles(const Tuple& t) const;
229 std::shared_ptr<polysolve::nonlinear::Problem> get_amips_energy(const Tuple& t) const;
230
235 //
239 bool is_inverted(const std::array<size_t, 3>& vs) const;
240 bool is_inverted(const Tuple& loc) const;
241 bool is_inverted(const size_t fid) const;
242 double get_quality(const std::array<size_t, 3>& vs) const;
243 double get_quality(const Tuple& loc) const;
244 double get_quality(const size_t fid) const;
245
246 double triangle_area(const size_t fid) const;
247
248 //
249 bool is_edge_on_surface(const Tuple& loc) const;
250 bool is_edge_on_surface(const std::array<size_t, 2>& vids) const;
251 bool is_edge_on_bbox(const Tuple& loc) const;
252 bool is_edge_on_bbox(const std::array<size_t, 2>& vids) const;
253 //
254 void mesh_improvement(int max_its = 80);
255 std::tuple<double, double> local_operations(
256 const std::array<int, 4>& ops,
257 bool collapse_limit_length = true);
258 std::tuple<double, double> get_max_avg_energy();
259
263 std::vector<ConnectedComponent> compute_connected_components(const CellTag& tag_in) const;
264 std::vector<ConnectedComponent> compute_connected_components(const ExprPtr& expr) const;
265
283 std::vector<ConnectedComponent> find_holes(const std::vector<CellTag>& tag_in) const;
284
292 void compute_tag_boundary(const CellTag& tag, MatrixXd& V, MatrixXi& E) const;
293
302 const std::vector<CellTag>& lcc_tags,
303 const size_t n_lcc = 1);
304
305 void fill_holes_topo(
306 const std::vector<CellTag>& fill_holes_tags,
307 double threshold = std::numeric_limits<double>::infinity());
308
309 void seal_connected_components(
310 const std::vector<CellTag>& tag_sets,
311 const std::vector<ConnectedComponent>& components);
312
313 void tight_seal_topo(
314 const std::vector<std::vector<CellTag>>& tight_seal_tag_sets,
315 double threshold = std::numeric_limits<double>::infinity());
316
317 void resolve_overlaps(const std::vector<std::array<ExprPtr, 2>>& intersecting_tags);
318
319 void replace_tags(const std::vector<CellTag>& tags_in, const std::vector<CellTag>& tags_out);
320
321 void tag_priority(const std::vector<int64_t>& tags_order);
322
323 bool vertex_is_on_surface(const size_t vid) const override
324 {
325 return m_vertex_attribute.at(vid).m_is_on_surface ||
326 !m_vertex_attribute.at(vid).on_bbox_faces.empty();
327 }
328 bool edge_is_on_surface(const std::array<size_t, 2>& vids) const override
329 {
330 if (!vertex_is_on_surface(vids[0]) || !vertex_is_on_surface(vids[1])) {
331 return false;
332 }
333
334 const auto [_, eid] = tuple_from_edge(vids);
335 bool on_surface = m_edge_attribute.at(eid).m_is_surface_fs;
336 bool on_bbox = m_edge_attribute.at(eid).m_is_bbox_fs >= 0;
337 return on_surface || on_bbox;
338 }
339
340private:
342
344 {
345 // VertexAttributes vertex_info;
346 size_t v_new;
347 size_t v1_id;
348 size_t v2_id;
349 std::vector<size_t> v1_param_type;
350 std::vector<size_t> v2_param_type;
351
352 EdgeAttributes old_e_attrs;
353
354 // std::vector<std::pair<EdgeAttributes, std::array<size_t, 2>>> changed_edges;
355 std::map<simplex::Edge, EdgeAttributes> changed_edges;
356
361 std::map<size_t, FaceAttributes> faces;
362 };
363 tbb::enumerable_thread_specific<SplitInfoCache> split_cache;
364
366 {
367 size_t v1_id;
368 size_t v2_id;
369 double max_energy;
370 double edge_length;
371 bool is_limit_length;
372
373 std::vector<std::pair<EdgeAttributes, std::array<size_t, 2>>> changed_edges;
374 // all faces incident to the delete vertex (v1) that are on the tracked surface
375 std::vector<std::array<size_t, 2>> surface_edges;
376 std::vector<size_t> changed_fids;
377 std::vector<double> changed_energies;
378 };
379 tbb::enumerable_thread_specific<CollapseInfoCache> collapse_cache;
380
381
383 {
384 double max_energy;
385 std::map<simplex::Edge, EdgeAttributes> changed_edges;
386 CellTag face_tags;
387 };
388 tbb::enumerable_thread_specific<SwapInfoCache> swap_cache;
389
390 // When set, split_edge_after binary-searches vmid onto the zero-crossing of this function.
391 // Negative = stays on v1 side, positive = stays on v2 side.
392 // Set before split_edge(), cleared immediately after.
393 std::function<double(const Vector2d&)> m_voronoi_split_fn = nullptr;
394};
395
396} // namespace wmtk::components::simwild::tri
Definition TriMesh.h:28
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:1479
Definition SimWildMeshTri.hpp:50
int m_is_bbox_fs
Definition SimWildMeshTri.hpp:64
Definition SimWildMeshTri.hpp:80
Definition SimWildMeshTri.hpp:89
double swap_weight(const Tuple &t) const
The quality improvement of a swap.
Definition SimWildMeshTri.cpp:1314
void init_from_image(const MatrixXd &V, const MatrixXi &T, const MatrixSi &T_tags, const std::vector< std::string > &tag_names)
Init from meshes image.
Definition SimWildMeshTri.cpp:167
void keep_largest_connected_component(const std::vector< CellTag > &lcc_tags, const size_t n_lcc=1)
Keep only the largest connected component for each of the distinct tag_0 values, and engulf all other...
Definition AnnotationsTri.cpp:443
std::vector< ConnectedComponent > compute_connected_components(const CellTag &tag_in) const
Find all connected components that contain the tag_in tags.
Definition AnnotationsTri.cpp:5
bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const override
Is an edge part of the substructure.
Definition SimWildMeshTri.hpp:328
void log_total_surface_energy()
Definition SimWildMeshTri.cpp:1636
SimWildMeshTri(Parameters &_m_params, double envelope_eps, int _num_threads=0)
Definition SimWildMeshTri.hpp:124
bool vertex_is_on_surface(const size_t vid) const override
Is a vertex part of the substructure.
Definition SimWildMeshTri.hpp:323
bool collapse_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge collapse including the link check as collapse...
Definition SimWildMeshTri.cpp:1060
void mesh_improvement(int max_its=80)
Definition SimWildMeshTri.cpp:1785
bool collapse_edge_after(const Tuple &t) override
User specified modifications and desideratas after an edge collapse.
Definition SimWildMeshTri.cpp:1224
bool smooth_after(const Tuple &t) override
User specified modifications and desideras after an edge smooth.
Definition SimWildMeshTri.cpp:1455
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 SimWildMeshTri.cpp:1344
bool swap_edge_after(const Tuple &t) override
User specified modifications and desideras after an edge swap.
Definition SimWildMeshTri.cpp:1380
void compute_tag_boundary(const CellTag &tag, MatrixXd &V, MatrixXi &E) const
Compute the boundary of a tag.
Definition AnnotationsTri.cpp:200
bool split_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge split.
Definition SimWildMeshTri.cpp:833
bool smooth_before(const Tuple &t) override
User specified preparations and desideratas for an edge smooth.
Definition SimWildMeshTri.cpp:1445
std::vector< ConnectedComponent > find_holes(const std::vector< CellTag > &tag_in) const
Find all regions that do not contain the tags from tag_in.
Definition AnnotationsTri.cpp:125
std::vector< Vector2d > get_surface_assembles(const Tuple &t) const
A vector containing the vertex position and all positions of the surface neighbors.
Definition SimWildMeshTri.cpp:1549
bool split_edge_after(const Tuple &loc) override
User specified modifications and desideratas after an edge split.
Definition SimWildMeshTri.cpp:876
Definition Parameters.h:7
std::map< size_t, FaceAttributes > faces
Definition SimWildMeshTri.hpp:361
Definition SimWildMeshTri.hpp:34