114 const std::array<size_t, 3>& vids,
138 void enable_finalize_attributes()
140 if (m_tet_finalize_enabled)
return;
141 m_tet_finalize.resize(m_tet_attribute.size());
142 m_tet_attr_group.add(&m_tet_finalize);
143 m_tet_finalize_enabled =
true;
147 enable_finalize_attributes();
148 return m_tet_finalize[tid];
150 const TetFinalizeAttributes& tet_finalize(
const size_t tid)
const
152 static const TetFinalizeAttributes defaults;
153 return m_tet_finalize_enabled ? m_tet_finalize[tid] : defaults;
160 bool m_tet_finalize_enabled =
false;
163 double cell_quality(
const size_t tid)
const override {
return m_tet_attribute[tid].m_quality; }
164 void set_cell_quality(
const size_t tid,
const double q)
override
166 m_tet_attribute[tid].m_quality = q;
168 bool allow_surface_swap()
const override {
return m_tet_params.allow_surface_swap; }
169 bool check_surface_topology()
const override {
return m_tet_params.check_surface_topology; }
172 m_vertex_extra[vid].m_is_on_open_boundary = is_open_boundary;
180 if (!m_vertex_extra[u].m_is_on_open_boundary) {
190 std::array<Eigen::Vector3d, 2>{
191 {m_vertex_attribute[vid].m_posf, m_vertex_attribute[u].m_posf}})) {
199 if (edge_length <= 0 || !m_vertex_extra[v1].m_is_on_open_boundary)
return true;
200 return m_vertex_extra[v2].m_is_on_open_boundary ||
201 !m_order2_envelope->is_outside(m_vertex_attribute[v2].m_posf);
204 bool collapse_is_order_2_edge(
const std::array<size_t, 2>& e)
override
206 return is_open_boundary_edge(e);
208 bool collapse_after_connectivity(
211 const std::vector<std::array<size_t, 2>>&)
override
213 m_vertex_extra[v2].m_is_on_open_boundary =
214 m_vertex_extra[v1].m_is_on_open_boundary || m_vertex_extra[v2].m_is_on_open_boundary;
215 m_vertex_extra[v2].m_is_on_feature_curve =
216 m_vertex_extra[v1].m_is_on_feature_curve || m_vertex_extra[v2].m_is_on_feature_curve;
219 void collapse_after_vertex(
size_t,
size_t v2)
override
221 if (m_vertex_extra[v2].m_is_on_open_boundary && !is_vertex_on_boundary(v2)) {
222 m_vertex_extra[v2].m_is_on_open_boundary =
false;
230 if (m_vertex_extra[v2].m_is_on_feature_curve && !vertex_has_feature_edge(v2)) {
231 m_vertex_extra[v2].m_is_on_feature_curve =
false;
237 m_vertex_extra[vid].m_is_on_feature_curve = on_feature;
242 std::shared_ptr<Envelope> smoothing_energy_envelope(
const size_t vid)
const override;
245 , m_tet_params(_m_params)
247 m_vertex_attr_group.add(&m_vertex_extra);
250 enable_feature_point_tracking(m_tet_params.preserve_feature_points);
251 NUM_THREADS = _num_threads;
252 m_tet_attr_group.add(&m_tet_attribute);
253 p_tet_attrs = &m_tet_attr_group;
254 m_collapse_check_link_condition =
false;
255 m_collapse_check_manifold =
false;
257 optimization::deactivate_opt_logger();
258 m_s_envelope = 1. / (m_params.eps * m_params.eps);
259 m_params.w_envelope = 1. - m_params.w_amips;
265 void create_mesh_attributes(
266 const std::vector<VertexAttributes>& _vertex_attribute,
267 const std::vector<TetAttributes>& _tet_attribute)
269 const size_t n_tet = _tet_attribute.size();
270 m_vertex_attribute.resize(_vertex_attribute.size());
273 m_vertex_extra.resize(_vertex_attribute.size());
274 m_feature_point_attribute.resize(_vertex_attribute.size());
275 m_face_attribute.resize(4 * n_tet);
276 m_tet_attribute.resize(n_tet);
281 for (
size_t i = 0; i < _vertex_attribute.size(); i++)
282 m_vertex_attribute[i] = _vertex_attribute[i];
293 const size_t tcap = std::max(n_tet, m_tet_attribute.size());
294 m_tet_attribute.m_attributes = std::vector<TetAttributes>(tcap);
295 for (
size_t i = 0; i < n_tet; i++) m_tet_attribute[i] = _tet_attribute[i];
296 for (
size_t i = 0; i < n_tet; i++)
297 m_tet_attribute[i].m_quality = get_quality(tuple_from_tet(i));
302 void output_mesh(std::string file);
307 MeshData tet_mesh_data();
308 void init_from_delaunay_box_mesh(
const std::vector<Eigen::Vector3d>& vertices);
316 bool is_vertex_on_boundary(
const size_t vid);
321 void mesh_improvement_legacy(
int max_its = 80);
327 Eigen::MatrixXd tet_barycenters(
const std::vector<Tuple>& tets)
const;
335 void compute_winding_number(
336 const std::vector<Tuple>& tets,
337 const Eigen::MatrixXd& barycenters,
338 const std::vector<Vector3d>& vertices = {},
339 const std::vector<std::array<size_t, 3>>& faces = {});
356 void compute_input_winding_numbers(
357 const std::vector<Tuple>& tets,
358 const Eigen::MatrixXd& barycenters,
359 const std::vector<Vector3d>& vertices,
360 const std::vector<std::array<size_t, 3>>& faces,
361 const std::vector<int>& face_input,
366 bool m_has_input_winding_number =
false;
367 bool m_has_tracked_winding_number =
false;
368 bool m_has_parts =
false;
370 void filter_with_input_surface_winding_number();
371 void filter_with_tracked_surface_winding_number();
372 void filter_with_flood_fill();
376 std::atomic<int> cnt_split = 0, cnt_collapse = 0;
387 std::vector<std::array<size_t, 3>> old_face_vids;
390 triangle_insertion_local_cache;
413 void insertion_by_volumeremesher(
414 const std::vector<Vector3d>& vertices,
415 const std::vector<std::array<size_t, 3>>& faces,
416 std::vector<Vector3r>& v_rational,
417 std::vector<std::array<size_t, 3>>& facets_after,
418 std::vector<bool>& is_v_on_input,
419 std::vector<std::array<size_t, 4>>& tets_after,
420 std::vector<bool>& tet_face_on_input_surface,
421 std::vector<int8_t>* tet_face_orientation =
nullptr,
422 const std::vector<Vector3d>& feature_edge_vertices = {},
423 const std::vector<std::array<size_t, 2>>& feature_edges = {},
424 const std::vector<Vector3d>& feature_points = {},
426 const std::vector<int>* face_input =
nullptr,
427 std::vector<InputSet>* facet_input_set =
nullptr,
428 std::vector<std::vector<uint32_t>>* facet_sources =
nullptr);
438 void init_from_Volumeremesher(
439 const std::vector<Vector3r>& v_rational,
440 const std::vector<std::array<size_t, 3>>& facets,
441 const std::vector<bool>& is_v_on_input,
442 const std::vector<std::array<size_t, 4>>& tets,
443 const std::vector<bool>& tet_face_on_input_surface,
444 const std::vector<int8_t>* tet_face_orientation =
nullptr,
446 const std::vector<Vector3d>* feature_anchors =
nullptr,
447 const std::vector<InputSet>* facet_input_set =
nullptr);
449 void init_from_file(std::string input_dir);
464 size_t refine_sizing_around_worst(
double max_energy)
override;
467 void find_open_boundary();
470 bool is_open_boundary_edge(
const Tuple& e)
override;
471 bool is_open_boundary_edge(
const std::array<size_t, 2>& e);
479 void init_vertex_order();
485 void save_paraview(
const std::string& path,
const bool use_hdf5, MeshMap* output =
nullptr);
486 void write_optimization_debug_output(
const std::string& path)
override
488 save_paraview(path,
false);
490 void optimization_sanity_checks_extra()
override;
503 VectorXd t_winding_number_input;
504 VectorXd t_winding_number_tracked;
505 MatrixXd t_winding_number_per_input;