3#include <wmtk/OptimizerParameters.h>
4#include <wmtk/RationalPositions.h>
5#include <wmtk/SurfaceTagAttributes.h>
6#include <wmtk/TriMesh.h>
7#include <wmtk/Types.hpp>
8#include <wmtk/envelope/Envelope.hpp>
9#include <wmtk/optimization/SmoothVertex.hpp>
10#include <wmtk/optimization/solver.hpp>
11#include <wmtk/threading/enumerable_thread_specific.hpp>
13#include <spdlog/fmt/bundled/format.h>
14#include <polysolve/nonlinear/Problem.hpp>
52 bool m_is_on_surface =
false;
53 std::vector<int> on_bbox_faces;
55 double m_sizing_scalar = 1;
57 size_t partition_id = 0;
62 , m_pos(to_rational(p))
65 VertexAttributes(
const Vector2r& p)
66 : m_posf(to_double(p))
76 double m_winding_number = 0;
77 std::set<int64_t> tags;
81 using VertAttCol = AttributeCollection<VertexAttributes>;
82 using EdgeAttCol = AttributeCollection<EdgeAttributes>;
83 using FaceAttCol = AttributeCollection<FaceAttributes>;
138 std::shared_ptr<SampleEnvelope> m_envelope;
139 double m_envelope_eps = -1;
144 double m_s_envelope = -1;
152 bool m_collapse_limit_length =
true;
153 int m_debug_print_counter = 0;
160 size_t m_tags_count = 0;
161 std::map<int64_t, std::string> m_tag_id_to_name;
162 std::map<std::string, int64_t> m_tag_name_to_id;
183 size_t get_partition_id(
const Tuple& loc)
const
185 return m_vertex_attribute[loc.vid(*
this)].partition_id;
187 void partition_mesh();
188 void partition_mesh_morton();
190 double get_length2(
const Tuple& l)
const;
200 bool is_inverted(
const std::array<size_t, 3>& vs)
const;
201 bool is_inverted(
const Tuple& loc)
const;
202 bool is_inverted(
const size_t fid)
const;
207 double get_quality(
const std::array<size_t, 3>& vs)
const;
208 double get_quality(
const Tuple& loc)
const;
209 double get_quality(
const size_t fid)
const;
211 std::tuple<double, double> get_max_avg_energy();
224 void mesh_improvement(
int max_its = 80);
225 std::tuple<double, double> local_operations(
226 const std::array<int, 4>& ops,
227 bool collapse_limit_length =
true);
229 std::set<simplex::Edge> m_force_split_edges;
230 size_t m_force_split_count = 0;
231 std::unique_ptr<std::atomic<int>[]> m_high_valence_claim;
232 size_t m_high_valence_claim_size = 0;
233 std::atomic<size_t> m_high_valence_rejects = 0;
235 bool is_force_split_edge(
const size_t v1,
const size_t v2)
const
237 return m_force_split_edges.find(
simplex::Edge(v1, v2)) != m_force_split_edges.end();
240 void split_all_edges();
244 void collapse_all_edges(
bool is_limit_length =
true);
274 size_t cells_before = 0;
275 size_t cells_after = 0;
276 double max_energy_before = 0.;
277 double max_energy_after = 0.;
289 double swap_weight(
const Tuple& t)
const;
304 Vector2d smoothing_position(
size_t vid)
const;
305 void set_smoothing_position(
size_t vid,
const Vector2d& p);
306 virtual bool smoothing_position_is_allowed(
size_t vid,
const Vector2d& p)
const = 0;
331 return m_vertex_attribute.at(vid).m_is_on_surface ? m_envelope :
nullptr;
333 virtual std::shared_ptr<SampleEnvelope> smoothing_containment_envelope(
const size_t vid)
const
335 return m_vertex_attribute.at(vid).m_is_on_surface ? m_envelope :
nullptr;
351 const size_t vid)
const
356 double active_quality_threshold()
const
360 virtual std::vector<size_t> active_vertices()
const;
377 return m_face_attribute.at(fid).m_quality /
m_params.stop_energy;
384 bool round(
const Tuple& v);
390 virtual double optimization_stop_metric()
const {
return m_params.stop_energy; }
391 virtual size_t refine_sizing_around_worst(
double max_metric) = 0;
412 virtual bool optimization_stop_at_float()
const {
return false; }
430 return (prev - cur) <=
m_params.stuck_refine_stall_eps * (cur - optimization_stop_metric());
452 write_smoothing_debug_output(fmt::format(
"debug_{}", m_debug_print_counter++));
456 virtual void collapse_pass_begin() {}
457 virtual void collapse_pass_end(
size_t) {}
458 virtual bool collapse_before_vertex(
size_t,
size_t) {
return true; }
459 virtual bool collapse_quality_allowed(
size_t v1,
size_t,
double q,
double ring_max)
const
464 virtual void collapse_after_vertex(
size_t,
size_t) {}
466 virtual bool split_adjust_position(
size_t,
const std::vector<Tuple>&) {
return true; }
467 virtual void split_after_vertex(
size_t) {}
469 virtual void write_smoothing_debug_output(
const std::string& path)
const = 0;
484 bool is_edge_on_surface(
const Tuple& loc)
const;
485 bool is_edge_on_surface(
const std::array<size_t, 2>& vids)
const;
486 bool is_edge_on_bbox(
const Tuple& loc)
const;
487 bool is_edge_on_bbox(
const std::array<size_t, 2>& vids)
const;
491 return m_vertex_attribute.at(vid).m_is_on_surface ||
492 !m_vertex_attribute.at(vid).on_bbox_faces.empty();
502 bool on_bbox = m_edge_attribute.at(eid).
m_is_bbox_fs >= 0;
503 return on_surface || on_bbox;
519 const std::array<size_t, 2>& vids)
const
529 if (!env)
return false;
530 const auto& VA = m_vertex_attribute;
531 return env->is_outside(std::array<Vector2d, 2>{{VA[a].m_posf, VA[b].m_posf}});
534 std::vector<std::array<size_t, 2>> get_edges_by_condition(
535 std::function<
bool(
const EdgeAttributes&)> cond)
const;
553 std::map<simplex::Edge, EdgeAttributes> changed_edges;
554 std::map<size_t, FaceAttributes> faces;
562 double max_energy = 0.;
563 double edge_length = 0.;
564 std::vector<std::pair<EdgeAttributes, std::array<size_t, 2>>> changed_edges;
565 std::vector<std::array<size_t, 2>> surface_edges;
566 std::vector<size_t> changed_fids;
567 std::vector<double> changed_energies;
581 std::map<simplex::Edge, EdgeAttributes> changed_edges;
582 std::set<int64_t> face_tags;
596 std::vector<size_t> ring;
597 std::vector<size_t> frontier;
598 std::vector<size_t> next;
599 std::vector<size_t> one_ring;
600 std::vector<uint32_t> stamp;
603 std::vector<std::pair<size_t, double>> saved_qualities;
608 const std::vector<size_t>&
618 size_t collapse_all_edges_impl(
bool is_limit_length,
int lock_ring,
size_t max_passes = 0);
Several attribute collections for the same simplex type, behind one container.
Definition AttributeCollection.hpp:132
The rounded/exact bookkeeping shared by every mesh that keeps both coordinates.
Definition RationalPositions.h:21
Whether a codimension-1 simplex is tracked surface, and which bbox side it lies on.
Definition SurfaceTagAttributes.h:15
int m_is_bbox_fs
Which bbox side this simplex is on; -1 for none.
Definition SurfaceTagAttributes.h:20
bool m_is_surface_fs
Is this simplex part of the tracked surface.
Definition SurfaceTagAttributes.h:18
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:2202
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:937
What triwild and simwild's 2D mesh share.
Definition TriOptimizerMesh.h:39
void smooth_all_vertices(size_t n_iters=1)
Run TriWild's vertex-smoothing pass.
Definition TriOptimizerMeshSmooth.cpp:63
bool smooth_after(const Tuple &t) override
User specified modifications and desideras after an edge smooth.
Definition TriOptimizerMeshSmooth.cpp:25
bool is_inverted_f(const Tuple &loc) const
Inversion check using only the double positions.
Definition TriOptimizerMesh.cpp:458
bool vertex_is_rounded(const size_t vid) const override
Whether this vertex's double position is currently trusted.
Definition TriOptimizerMesh.h:474
bool vertex_is_on_surface(const size_t vid) const override
Is a vertex part of the substructure.
Definition TriOptimizerMesh.h:489
std::vector< size_t > all_vertex_ids() const override
Every live vertex, in the mesh's own iteration order.
Definition TriOptimizerMesh.cpp:518
bool smooth_vertex_reversible(size_t vid, CoarsenScratch &scr)
One smoothing attempt on vid, restoring everything it wrote if it is rejected.
Definition TriOptimizerMeshCollapse.cpp:444
AttributeContainerGroup m_edge_attr_group
What p_edge_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:111
AttributeContainerGroup m_vertex_attr_group
What p_vertex_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:96
virtual std::shared_ptr< SampleEnvelope > surface_envelope_for_edge(const std::array< size_t, 2 > &vids) const
Envelope the tracked-surface segment vids must stay inside.
Definition TriOptimizerMesh.h:518
size_t coarsen_mesh()
Coarsen the mesh without letting the max energy rise.
Definition TriOptimizerMeshCollapse.cpp:485
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 TriOptimizerMesh.cpp:328
virtual double quality_rel(const size_t fid) const
A face's quality relative to the quality it is required to reach; <= 1 means it meets it.
Definition TriOptimizerMesh.h:375
virtual std::shared_ptr< SampleEnvelope > smoothing_energy_envelope(const size_t vid) const
The envelope this vertex is PULLED TOWARD while smoothing, and the one it is CONTAINED BY afterwards....
Definition TriOptimizerMesh.h:329
bool coarsen_collapse_edge(const Tuple &e, std::vector< Tuple > &new_tris)
One collapse under the coarsening rules, outside a coarsening pass.
Definition TriOptimizerMeshCollapse.cpp:473
static constexpr double MAX_ENERGY
The sentinel get_quality returns for a face AMIPS2D cannot score.
Definition TriOptimizerMesh.h:132
void gradation_smooth_sizing(double grade, const std::vector< size_t > &seeds)
Monotone (only-decreasing) gradation smoothing of the sizing field.
Definition TriOptimizerMesh.cpp:384
bool m_coarsen_mode
Set for the duration of coarsen_mesh(); read-only while a pass is running.
Definition TriOptimizerMesh.h:575
size_t swap_all_edges()
Run TriWild's quality-improving interior edge-flip pass.
Definition TriOptimizerMesh.cpp:281
const std::vector< size_t > & collect_vertex_ball(const size_t *seeds, size_t n_seeds, int n, CoarsenScratch &scr) const
Vertices within n edges of seeds, in BFS order. Uses coarsen_scratch.
Definition TriOptimizerMeshCollapse.cpp:377
bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const override
Is an edge part of the substructure.
Definition TriOptimizerMesh.h:494
TriOptimizerMesh(OptimizerParameters ¶ms)
Definition TriOptimizerMesh.h:164
virtual bool optimization_stalled(double prev, double cur)
Whether an iteration that moved the metric from prev to cur is stalled, and the sizing refinement sho...
Definition TriOptimizerMesh.h:428
bool surface_segment_is_outside(const size_t a, const size_t b) const
Definition TriOptimizerMesh.h:526
AttributeContainerGroup m_face_attr_group
What p_face_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:122
optimization::SmoothRejectCounters m_smooth_rejects
Why smoothing attempts were refused, reported once per pass.
Definition TriOptimizerMesh.h:150
OptimizerParameters & m_params
Definition TriOptimizerMesh.h:136
std::string m_debug_pass_name
Definition TriOptimizerMesh.h:158
double m_s_amips
Definition TriOptimizerMesh.h:143
bool swap_edge_after(const Tuple &t) override
User specified modifications and desideras after an edge swap.
Definition TriOptimizerMesh.cpp:357
bool collapse_edge_after(const Tuple &t) override
User specified modifications and desideratas after an edge collapse.
Definition TriOptimizerMeshCollapse.cpp:300
bool round_vertex(const size_t vid) override
Definition TriOptimizerMesh.h:481
bool round(const Tuple &v)
Round a vertex position to floating point, if that inverts no incident face.
Definition TriOptimizerMesh.cpp:529
virtual bool optimization_bare_coarsen_passes() const
Whether the loop opens and closes with BARE collapse passes.
Definition TriOptimizerMesh.h:405
int m_iterations_used
Shared TriWild/SimWild outer optimization schedule.
Definition TriOptimizerMesh.h:223
bool split_edge_after(const Tuple &loc) override
User specified modifications and desideratas after an edge split.
Definition TriOptimizerMeshSplit.cpp:171
double region_max_quality_rel(const std::vector< size_t > &vids) const
Definition TriOptimizerMeshCollapse.cpp:433
virtual std::shared_ptr< polysolve::nonlinear::Problem > smoothing_extra_energy(const size_t vid) const
An extra term the application adds to this vertex's smoothing objective, or null.
Definition TriOptimizerMesh.h:350
virtual std::tuple< double, double > optimization_quality_stats()
Definition TriOptimizerMesh.cpp:27
bool split_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge split.
Definition TriOptimizerMeshSplit.cpp:101
virtual void optimization_debug_checkpoint()
Called at every pass boundary, whether or not debug output is on.
Definition TriOptimizerMesh.h:449
bool collapse_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge collapse including the link check as collapse...
Definition TriOptimizerMeshCollapse.cpp:98
uint32_t m_op_epoch
Definition TriOptimizerMesh.h:411
virtual void update_attributes()
Update the attributes of the mesh after an iteration of operations.
Definition TriOptimizerMesh.h:220
bool smooth_before(const Tuple &t) override
User specified preparations and desideratas for an edge smooth.
Definition TriOptimizerMeshSmooth.cpp:12
Definition Simplex.hpp:46
Definition enumerable_thread_specific.hpp:26
The parameters tetwild, triwild and simwild all share.
Definition OptimizerParameters.h:29
Per-thread buffers for the coarsening composite, so it allocates nothing.
Definition TriOptimizerMesh.h:595
What coarsen_mesh() achieved, for the run report. Zeroed when the pass is off.
Definition TriOptimizerMesh.h:272
Definition TriOptimizerMesh.h:559
double region_max_rel_before
Definition TriOptimizerMesh.h:570
Definition TriOptimizerMesh.h:74
Definition TriOptimizerMesh.h:549
Definition TriOptimizerMesh.h:579
Definition TriOptimizerMesh.h:42
bool m_is_rounded
Definition TriOptimizerMesh.h:50
Why a smoothing attempt was refused, counted per pass.
Definition SmoothVertex.hpp:31