104 double time_env = 0.0;
105 igl::Timer isout_timer;
106 const double MAX_ENERGY = 1e50;
115 : m_params(_m_params)
116 , m_envelope(_m_envelope)
118 NUM_THREADS = _num_threads;
119 p_vertex_attrs = &m_vertex_attribute;
120 p_face_attrs = &m_face_attribute;
121 p_tet_attrs = &m_tet_attribute;
122 m_collapse_check_link_condition =
false;
123 m_collapse_check_manifold =
false;
137 void create_mesh_attributes(
138 const std::vector<VertexAttributes>& _vertex_attribute,
139 const std::vector<TetAttributes>& _tet_attribute)
141 auto n_tet = _tet_attribute.size();
142 m_vertex_attribute.resize(_vertex_attribute.size());
143 m_face_attribute.resize(4 * n_tet);
144 m_tet_attribute.resize(n_tet);
149 for (
auto i = 0; i < _vertex_attribute.size(); i++)
150 m_vertex_attribute[i] = _vertex_attribute[i];
151 m_tet_attribute.m_attributes = tbb::concurrent_vector<TetAttributes>(_tet_attribute.size());
152 for (
auto i = 0; i < _tet_attribute.size(); i++) m_tet_attribute[i] = _tet_attribute[i];
153 for (
auto i = 0; i < _tet_attribute.size(); i++)
158 void compute_vertex_partition()
160 auto partition_id = partition_TetMesh(*
this, NUM_THREADS);
162 m_vertex_attribute[i].partition_id = partition_id[i];
166 void compute_vertex_partition_morton()
168 if (NUM_THREADS == 0)
return;
170 wmtk::logger().info(
"Number of parts: {} by morton", NUM_THREADS);
172 tbb::task_arena arena(NUM_THREADS);
178 tbb::blocked_range<size_t>(0, V_v.size()),
179 [&](tbb::blocked_range<size_t> r) {
180 for (size_t i = r.begin(); i < r.end(); i++) {
181 V_v[i] = m_vertex_attribute[i].m_posf;
192 std::vector<sortstruct> list_v;
193 list_v.resize(V_v.size());
196 std::vector<Eigen::Vector3d> V = V_v;
197 Eigen::Vector3d vmin, vmax;
201 for (
size_t j = 0; j < V.size(); j++) {
202 for (
int i = 0; i < 3; i++) {
203 vmin(i) = std::min(vmin(i), V[j](i));
204 vmax(i) = std::max(vmax(i), V[j](i));
209 Eigen::Vector3d center = (vmin + vmax) / 2;
212 tbb::blocked_range<size_t>(0, V.size()),
213 [&](tbb::blocked_range<size_t> r) {
214 for (size_t i = r.begin(); i < r.end(); i++) {
215 V[i] = V[i] - center;
219 Eigen::Vector3d scale_point =
222 double xscale, yscale, zscale;
223 xscale = fabs(scale_point[0]);
224 yscale = fabs(scale_point[1]);
225 zscale = fabs(scale_point[2]);
226 double scale = std::max(std::max(xscale, yscale), zscale);
229 tbb::blocked_range<size_t>(0, V.size()),
230 [&](tbb::blocked_range<size_t> r) {
231 for (size_t i = r.begin(); i < r.end(); i++) {
237 constexpr int multi = 1000;
239 tbb::blocked_range<size_t>(0, V.size()),
240 [&](tbb::blocked_range<size_t> r) {
241 for (size_t i = r.begin(); i < r.end(); i++) {
242 list_v[i].morton = Resorting::MortonCode64(
243 int(V[i][0] * multi),
244 int(V[i][1] * multi),
245 int(V[i][2] * multi));
250 const auto morton_compare = [](
const sortstruct& a,
const sortstruct& b) {
251 return (a.morton < b.morton);
254 tbb::parallel_sort(list_v.begin(), list_v.end(), morton_compare);
256 size_t interval = list_v.size() / NUM_THREADS + 1;
259 tbb::blocked_range<size_t>(0, list_v.size()),
260 [&](tbb::blocked_range<size_t> r) {
261 for (size_t i = r.begin(); i < r.end(); i++) {
262 m_vertex_attribute[list_v[i].order].partition_id = i / interval;
268 size_t get_partition_id(
const Tuple& loc)
const
270 return m_vertex_attribute[loc.vid(*
this)].partition_id;
275 void output_mesh(std::string file);
276 void output_faces(std::string file, std::function<
bool(
const FaceAttributes&)> cond);
278 void init_from_delaunay_box_mesh(
const std::vector<Eigen::Vector3d>& vertices);
280 void finalize_triangle_insertion(
const std::vector<std::array<size_t, 3>>& faces);
282 void init_from_input_surface(
283 const std::vector<Vector3d>& vertices,
284 const std::vector<std::array<size_t, 3>>& faces,
285 const std::vector<size_t>& partition_id);
286 bool triangle_insertion_before(
const std::vector<Tuple>& faces)
override;
287 bool triangle_insertion_after(
const std::vector<std::vector<Tuple>>& new_faces)
override;
290 void split_all_edges();
291 bool split_edge_before(
const Tuple& t)
override;
292 bool split_edge_after(
const Tuple& loc)
override;
294 void smooth_all_vertices();
295 bool smooth_before(
const Tuple& t)
override;
296 bool smooth_after(
const Tuple& t)
override;
298 void collapse_all_edges(
bool is_limit_length =
true);
299 bool collapse_edge_before(
const Tuple& t)
override;
300 bool collapse_edge_after(
const Tuple& t)
override;
302 size_t swap_all_edges_44();
303 bool swap_edge_44_before(
const Tuple& t)
override;
304 double swap_edge_44_energy(
const std::vector<std::array<size_t, 4>>& tets,
const int op_case)
306 bool swap_edge_44_after(
const Tuple& t)
override;
308 size_t swap_all_edges_56();
309 bool swap_edge_56_before(
const Tuple& t)
override;
310 double swap_edge_56_energy(
const std::vector<std::array<size_t, 4>>& tets,
const int op_case)
312 bool swap_edge_56_after(
const Tuple& t)
override;
314 size_t swap_all_edges_32();
315 bool swap_edge_before(
const Tuple& t)
override;
316 bool swap_edge_after(
const Tuple& t)
override;
318 size_t swap_all_faces();
319 bool swap_face_before(
const Tuple& t)
override;
320 bool swap_face_after(
const Tuple& t)
override;
322 size_t swap_all_edges_all();
327 bool is_inverted_f(
const Tuple& loc)
const;
328 bool is_inverted(
const std::array<size_t, 4>& vs)
const;
329 bool is_inverted(
const Tuple& loc)
const;
330 double get_quality(
const std::array<size_t, 4>& vs)
const;
331 double get_quality(
const Tuple& loc)
const;
332 bool round(
const Tuple& loc);
334 bool is_edge_on_surface(
const Tuple& loc);
335 bool is_edge_on_bbox(
const Tuple& loc);
340 bool is_vertex_on_boundary(
const size_t vid);
342 void mesh_improvement(
int max_its = 80);
346 void mesh_improvement_legacy(
int max_its = 80);
347 std::tuple<double, double> local_operations(
348 const std::array<int, 4>& ops,
349 bool collapse_limit_length =
true);
350 std::tuple<double, double> get_max_avg_energy();
358 void compute_winding_number(
359 const std::vector<Vector3d>& vertices = {},
360 const std::vector<std::array<size_t, 3>>& faces = {});
362 void compute_winding_numbers(
const std::vector<std::string>& input_paths);
364 void filter_with_input_surface_winding_number();
365 void filter_with_tracked_surface_winding_number();
366 void filter_with_flood_fill();
368 bool check_attributes();
370 std::vector<std::array<size_t, 3>> get_faces_by_condition(
371 std::function<
bool(
const FaceAttributes&)> cond)
const;
373 bool invariants(
const std::vector<Tuple>& t)
override;
375 double get_length2(
const Tuple& loc)
const;
377 std::atomic<int> cnt_split = 0, cnt_collapse = 0, cnt_swap = 0;
382 tbb::concurrent_map<std::array<size_t, 3>, std::vector<int>> tet_face_tags;
388 std::vector<std::array<size_t, 3>> old_face_vids;
390 tbb::enumerable_thread_specific<TriangleInsertionLocalInfoCache> triangle_insertion_local_cache;
399 bool is_edge_on_surface =
false;
400 bool is_edge_open_boundary =
false;
401 size_t edge_order = 0;
402 std::vector<size_t> v1_param_type;
403 std::vector<size_t> v2_param_type;
405 std::vector<std::pair<FaceAttributes, std::array<size_t, 3>>> changed_faces;
407 tbb::enumerable_thread_specific<SplitInfoCache> split_cache;
415 bool is_limit_length;
417 std::vector<std::pair<FaceAttributes, std::array<size_t, 3>>> changed_faces;
419 std::vector<std::array<size_t, 3>> surface_faces;
421 std::vector<std::array<size_t, 2>> boundary_edges;
422 std::vector<size_t> changed_tids;
423 std::vector<double> changed_energies;
425 std::vector<std::array<size_t, 2>> failed_edges;
427 std::map<std::pair<size_t, size_t>,
int> edge_link;
428 std::map<size_t, int> vertex_link;
429 size_t global_nonmani_ver_cnt;
432 std::vector<size_t> one_ring_surface_vertices;
433 std::vector<std::pair<size_t, size_t>> one_ring_surface_edges;
434 std::vector<std::array<size_t, 3>> one_ring_surface;
437 std::vector<size_t> edge_incident_param_type;
439 tbb::enumerable_thread_specific<CollapseInfoCache> collapse_cache;
447 tbb::enumerable_thread_specific<SwapInfoCache> swap_cache;
455 void insertion_by_volumeremesher_old(
456 const std::vector<Vector3d>& vertices,
457 const std::vector<std::array<size_t, 3>>& faces,
458 std::vector<Vector3r>& v_rational,
459 std::vector<std::array<size_t, 3>>& facets_after,
460 std::vector<bool>& is_v_on_input,
461 std::vector<std::array<size_t, 4>>& tets_after,
462 std::vector<bool>& tet_face_on_input_surface);
468 void insertion_by_volumeremesher(
469 const std::vector<Vector3d>& vertices,
470 const std::vector<std::array<size_t, 3>>& faces,
471 std::vector<Vector3r>& v_rational,
472 std::vector<std::array<size_t, 3>>& facets_after,
473 std::vector<bool>& is_v_on_input,
474 std::vector<std::array<size_t, 4>>& tets_after,
475 std::vector<bool>& tet_face_on_input_surface);
477 void init_from_Volumeremesher(
478 const std::vector<Vector3r>& v_rational,
479 const std::vector<std::array<size_t, 3>>& facets,
480 const std::vector<bool>& is_v_on_input,
481 const std::vector<std::array<size_t, 4>>& tets,
482 const std::vector<bool>& tet_face_on_input_surface);
484 void init_from_file(std::string input_dir);
486 std::vector<std::array<size_t, 3>> triangulate_polygon_face(std::vector<Vector3r> points);
487 bool check_polygon_face_validity(std::vector<Vector3r> points);
489 bool check_nondegenerate_tets();
490 void output_embedded_polygon_mesh(
491 std::string output_dir,
492 const std::vector<Vector3r>& v_rational,
493 const std::vector<std::vector<size_t>>& polygon_faces,
494 const std::vector<std::vector<size_t>>& polygon_cells,
495 const std::vector<bool>& polygon_faces_on_input_surface);
497 void output_embedded_polygon_surface_mesh(
498 std::string output_dir,
499 const std::vector<Vector3r>& v_rational,
500 const std::vector<std::vector<size_t>>& polygon_faces,
501 const std::vector<bool>& polygon_faces_on_input_surface);
503 void output_tetrahedralized_embedded_mesh(
504 std::string output_dir,
505 const std::vector<Vector3r>& v_rational,
506 const std::vector<std::array<size_t, 3>>& facets,
507 const std::vector<std::array<size_t, 4>>& tets,
508 const std::vector<bool>& tet_face_on_input_surface);
510 void output_init_tetmesh(std::string output_dir);
512 void output_tracked_surface(std::string output_file);
514 bool adjust_sizing_field_serial(
double max_energy);
517 void find_open_boundary();
518 bool is_open_boundary_edge(
const Tuple& e);
519 bool is_open_boundary_edge(
const std::array<size_t, 2>& e);
524 bool vertex_is_on_surface(
const size_t vid)
const override;
526 bool face_is_on_surface(
const size_t fid)
const override;
528 size_t get_order_of_vertex(
const size_t vid)
const override;
532 void init_vertex_order();
537 vol_rem::bigrational px,
538 vol_rem::bigrational py,
539 vol_rem::bigrational pz,
540 vol_rem::bigrational qx,
541 vol_rem::bigrational qy,
542 vol_rem::bigrational qz,
543 vol_rem::bigrational rx,
544 vol_rem::bigrational ry,
545 vol_rem::bigrational rz,
546 vol_rem::bigrational sx,
547 vol_rem::bigrational sy,
548 vol_rem::bigrational sz);
557 int orient3D_wmtk_rational(
571 bool checkTrackedFaces_wmtk_rational(
572 std::vector<wmtk::Rational>& vol_coords,
573 const std::vector<double>& surf_coords,
574 std::vector<uint32_t>& facets,
575 std::vector<uint32_t>& facets_on_input,
576 const std::vector<uint32_t>& surf_tris);
578 bool check_vertex_param_type();
583 void save_paraview(
const std::string& path,
const bool use_hdf5);
586 void init_sizing_field();
598 VectorXd t_winding_number_input;
599 VectorXd t_winding_number_tracked;
600 MatrixXd t_winding_number_per_input;