3#include <wmtk/OptimizerParameters.h>
4#include <wmtk/RationalPositions.h>
5#include <wmtk/SurfaceTagAttributes.h>
6#include <wmtk/TriMesh.h>
7#include <wmtk/ExactPosition.hpp>
8#include <wmtk/Types.hpp>
9#include <wmtk/envelope/Envelope.hpp>
10#include <wmtk/history/History.hpp>
11#include <wmtk/optimization/SmoothVertex.hpp>
12#include <wmtk/optimization/solver.hpp>
13#include <wmtk/threading/enumerable_thread_specific.hpp>
15#include <spdlog/fmt/bundled/format.h>
16#include <polysolve/nonlinear/Problem.hpp>
54 bool m_is_on_surface =
false;
55 std::vector<int> on_bbox_faces;
57 double m_sizing_scalar = 1;
59 size_t partition_id = 0;
70 Vector2r pos()
const {
return m_exact.
value(m_posf); }
71 bool pos_coord_equals(
int k,
const Rational& r)
const
75 void set_pos(
const Vector2r& p) { m_exact.
store(p); }
76 void set_pos_to_posf() { m_exact.
clear(); }
77 ExactPosition<Vector2r, Vector2d> m_exact;
81 VertexAttributes(
const Vector2d& p)
85 VertexAttributes(
const Vector2r& p)
86 : m_posf(to_double(p))
97 double m_winding_number = 0;
98 std::set<int64_t> tags;
102 using VertAttCol = AttributeCollection<VertexAttributes>;
103 using EdgeAttCol = AttributeCollection<EdgeAttributes>;
104 using FaceAttCol = AttributeCollection<FaceAttributes>;
177 std::shared_ptr<Envelope> m_envelope;
178 double m_envelope_eps = -1;
183 double m_s_envelope = -1;
191 bool m_collapse_limit_length =
true;
192 int m_debug_print_counter = 0;
199 size_t m_tags_count = 0;
200 std::map<int64_t, std::string> m_tag_id_to_name;
201 std::map<std::string, int64_t> m_tag_name_to_id;
292 "{}() called while an operation pass runs; call it before or after the pass.",
340 std::pair<size_t, size_t>
feature_retention(
double* worst_ratio =
nullptr)
const;
362 size_t get_partition_id(
const Tuple& loc)
const
364 return m_vertex_attribute[loc.vid(*
this)].partition_id;
366 void partition_mesh();
367 void partition_mesh_morton();
369 double get_length2(
const Tuple& l)
const;
379 bool is_inverted(
const std::array<size_t, 3>& vs)
const;
386 double get_quality(
const std::array<size_t, 3>& vs)
const;
387 double get_quality(
const Tuple& loc)
const;
388 double get_quality(
const size_t fid)
const;
390 std::tuple<double, double> get_max_avg_energy();
403 void mesh_improvement(
int max_its = 80);
404 std::tuple<double, double> local_operations(
405 const std::array<int, 4>& ops,
406 bool collapse_limit_length =
true);
408 std::set<simplex::Edge> m_force_split_edges;
409 size_t m_force_split_count = 0;
410 std::unique_ptr<std::atomic<int>[]> m_high_valence_claim;
411 size_t m_high_valence_claim_size = 0;
412 std::atomic<size_t> m_high_valence_rejects = 0;
425 if (!m_high_valence_claim)
return;
426 const size_t n = std::max(
vert_capacity(), m_vertex_attribute.size());
427 if (n <= m_high_valence_claim_size)
return;
428 auto grown = std::make_unique<std::atomic<int>[]>(n);
429 for (
size_t i = 0; i < m_high_valence_claim_size; ++i) {
430 grown[i].store(m_high_valence_claim[i].load(std::memory_order_relaxed));
432 m_high_valence_claim = std::move(grown);
433 m_high_valence_claim_size = n;
442 size_t m_split_order_wait_defects = 0;
444 bool is_force_split_edge(
const size_t v1,
const size_t v2)
const
446 return m_force_split_edges.find(
simplex::Edge(v1, v2)) != m_force_split_edges.end();
449 void split_all_edges();
453 void collapse_all_edges(
bool is_limit_length =
true);
483 size_t cells_before = 0;
484 size_t cells_after = 0;
485 double max_energy_before = 0.;
486 double max_energy_after = 0.;
498 double swap_weight(
const Tuple& t)
const;
529 Vector2d smoothing_position(
size_t vid)
const;
530 void set_smoothing_position(
size_t vid,
const Vector2d& p);
563 return m_vertex_attribute.at(vid).m_is_on_surface ? m_envelope :
nullptr;
574 const std::array<size_t, 2>& edge,
593 const size_t vid)
const
610 double active_quality_threshold()
const
614 virtual std::vector<size_t> active_vertices()
const;
631 return m_face_attribute.at(fid).m_quality /
m_params.stop_energy;
638 bool round(
const Tuple& v);
644 virtual double optimization_stop_metric()
const {
return m_params.stop_energy; }
645 virtual size_t refine_sizing_around_worst(
double max_metric) = 0;
667 virtual bool optimization_stop_at_float()
const {
return false; }
685 return (prev - cur) <=
m_params.stuck_refine_stall_eps * (cur - optimization_stop_metric());
707 write_smoothing_debug_output(fmt::format(
"debug_{}", m_debug_print_counter++));
711 virtual void collapse_pass_begin() {}
712 virtual void collapse_pass_end(
size_t) {}
713 virtual bool collapse_before_vertex(
size_t,
size_t) {
return true; }
714 virtual bool collapse_quality_allowed(
size_t v1,
size_t,
double q,
double ring_max)
const
719 virtual void collapse_after_vertex(
size_t,
size_t) {}
732 return after < before;
735 virtual bool split_adjust_position(
size_t,
const std::vector<Tuple>&) {
return true; }
736 virtual void split_after_vertex(
size_t) {}
738 virtual void write_smoothing_debug_output(
const std::string& path)
const = 0;
753 bool is_edge_on_surface(
const Tuple& loc)
const;
761 using CurveSources = std::map<std::array<size_t, 2>, std::vector<uint64_t>>;
782 std::shared_ptr<history::TrackedCurveRecorder> m_recorded_curves;
783 std::vector<std::vector<uint64_t>> m_recorded_curve_sources;
786 bool is_edge_on_surface(
const std::array<size_t, 2>& vids)
const;
787 bool is_edge_on_bbox(
const Tuple& loc)
const;
788 bool is_edge_on_bbox(
const std::array<size_t, 2>& vids)
const;
792 return m_vertex_attribute.at(vid).m_is_on_surface ||
793 !m_vertex_attribute.at(vid).on_bbox_faces.empty();
803 bool on_bbox = m_edge_attribute.at(eid).
m_is_bbox_fs >= 0;
804 return on_surface || on_bbox;
823 const std::array<size_t, 2>& vids,
836 if (!env)
return false;
837 const auto& VA = m_vertex_attribute;
838 return env->is_outside(std::array<Vector2d, 2>{{VA[a].m_posf, VA[b].m_posf}});
841 std::vector<std::array<size_t, 2>> get_edges_by_condition(
842 std::function<
bool(
const EdgeAttributes&)> cond)
const;
860 std::map<simplex::Edge, EdgeAttributes> changed_edges;
861 std::map<size_t, FaceAttributes> faces;
869 double max_energy = 0.;
870 double edge_length = 0.;
871 std::vector<std::pair<EdgeAttributes, std::array<size_t, 2>>> changed_edges;
879 std::vector<size_t> changed_fids;
880 std::vector<double> changed_energies;
894 std::map<simplex::Edge, EdgeAttributes> changed_edges;
895 std::set<int64_t> face_tags;
909 std::vector<size_t> ring;
910 std::vector<size_t> frontier;
911 std::vector<size_t> next;
912 std::vector<size_t> one_ring;
913 std::vector<uint32_t> stamp;
916 std::vector<std::pair<size_t, double>> saved_qualities;
921 const std::vector<size_t>&
931 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:143
bool coord_equals(int k, const VecD &posf, const Rational &r) const
Whether coordinate k equals r, without materialising the whole position.
Definition ExactPosition.hpp:54
void store(const VecR &p)
Store an exact position that may differ from the double one.
Definition ExactPosition.hpp:60
VecR value(const VecD &posf) const
The exact position of a vertex whose double position is posf.
Definition ExactPosition.hpp:51
void clear()
The exact position is the double one: drop the stored copy.
Definition ExactPosition.hpp:70
Definition Rational.hpp:10
The rounded/exact bookkeeping shared by every mesh that keeps both coordinates.
Definition RationalPositions.h:21
Definition SurfaceTagAttributes.h:24
int8_t m_is_bbox_fs
Which bbox side this simplex is on; -1 for none.
Definition SurfaceTagAttributes.h:48
bool m_is_surface_fs
Is this simplex part of the tracked surface.
Definition SurfaceTagAttributes.h:46
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:622
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:2484
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:1056
What triwild and simwild's 2D mesh share.
Definition TriOptimizerMesh.h:42
std::vector< size_t > tracked_feature_points() const override
Definition TriOptimizerMesh.cpp:730
void smooth_all_vertices(size_t n_iters=1)
Run TriWild's vertex-smoothing pass.
Definition TriOptimizerMeshSmooth.cpp:66
void on_slot_storage_grown() override
Definition TriOptimizerMesh.h:423
std::map< std::array< size_t, 2 >, std::vector< uint64_t > > CurveSources
Definition TriOptimizerMesh.h:761
bool smooth_after(const Tuple &t) override
User specified modifications and desideras after an edge smooth.
Definition TriOptimizerMeshSmooth.cpp:28
bool is_inverted_f(const Tuple &loc) const
Inversion check using only the double positions.
Definition TriOptimizerMesh.cpp:465
bool surface_segment_is_outside(const size_t a, const size_t b, const EdgeAttributes &attr) const
Definition TriOptimizerMesh.h:832
bool vertex_is_rounded(const size_t vid) const override
Whether this vertex's double position is currently trusted.
Definition TriOptimizerMesh.h:743
bool vertex_is_on_surface(const size_t vid) const override
Is a vertex part of the substructure.
Definition TriOptimizerMesh.h:790
std::vector< size_t > all_vertex_ids() const override
Every live vertex, in the mesh's own iteration order.
Definition TriOptimizerMesh.cpp:525
bool use_colored_smoothing() const
Whether this pass smooths by color class (see OptimizerParameters::colored_smoothing).
Definition TriOptimizerMeshSmooth.cpp:102
bool feature_point_ball_contains(const size_t vid, const Vector2d &p) const
May vertex vid sit at p as far as its anchor goes?
Definition TriOptimizerMesh.cpp:800
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:506
std::optional< history::CurveHistory > finish_curve_history(const history::CurveHistory *input=nullptr)
Check the recorded curves against the tracked edges, stop recording, log what the history holds and r...
Definition TriOptimizerMesh.cpp:679
bool m_preserve_feature_points
Whether the collapse and smoothing policy is on (its preserve argument).
Definition TriOptimizerMesh.h:266
AttributeContainerGroup m_edge_attr_group
What p_edge_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:150
AttributeContainerGroup m_vertex_attr_group
What p_vertex_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:135
virtual double smoothing_cell_energy(const size_t, const double quality) const
The number the shared smoother compares for one face, given the face's quality at the position being ...
Definition TriOptimizerMesh.h:605
std::vector< std::pair< size_t, int > > tracked_curve_boundary() const
Vertices where the oriented tracked curves have a boundary (in minus out != 0), each with that sum....
Definition TriOptimizerMesh.cpp:611
size_t coarsen_mesh()
Coarsen the mesh without letting the max energy rise.
Definition TriOptimizerMeshCollapse.cpp:547
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:333
void record_curve_history(const std::string &metadata, const CurveSources &sources={})
Definition TriOptimizerMesh.cpp:649
bool m_in_operation_pass
True while a pass of the shared operations runs.
Definition TriOptimizerMesh.h:281
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:629
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:535
static constexpr double MAX_ENERGY
The sentinel get_quality returns for a face AMIPS2D cannot score.
Definition TriOptimizerMesh.h:171
void gradation_smooth_sizing(double grade, const std::vector< size_t > &seeds)
Monotone (only-decreasing) gradation smoothing of the sizing field.
Definition TriOptimizerMesh.cpp:391
virtual bool swap_quality_allowed(double after, double before, bool) const
Definition TriOptimizerMesh.h:730
bool m_coarsen_mode
Set for the duration of coarsen_mesh(); read-only while a pass is running.
Definition TriOptimizerMesh.h:888
std::vector< std::array< size_t, 2 > > oriented_tracked_edges() const
Definition TriOptimizerMesh.cpp:597
size_t swap_all_edges()
Run TriWild's quality-improving interior edge-flip pass.
Definition TriOptimizerMesh.cpp:286
size_t m_split_order_waits
The current split pass's ExecutePass::waits() and wait_defects().
Definition TriOptimizerMesh.h:441
void smooth_vertices_colored(const std::vector< std::pair< std::string, Tuple > > &ops)
One smoothing sweep over ops (all "vertex_smooth"), one color class at a time.
Definition TriOptimizerMeshSmooth.cpp:107
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:439
bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const override
Is an edge part of the substructure.
Definition TriOptimizerMesh.h:795
TriOptimizerMesh(OptimizerParameters ¶ms)
Definition TriOptimizerMesh.h:343
virtual std::shared_ptr< Envelope > 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:561
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:683
bool collapse_breaks_feature_point(const size_t v1_id, const size_t v2_id) const
Definition TriOptimizerMesh.cpp:775
void enable_feature_point_tracking(const bool preserve)
Turn on feature-point tracking, and the policy when preserve.
Definition TriOptimizerMesh.h:309
virtual bool smoothing_position_is_allowed(const size_t vid, const Vector2d &p) const
Definition TriOptimizerMesh.h:535
bool m_track_feature_points
Whether the shared operations maintain the ids (enable_feature_point_tracking()).
Definition TriOptimizerMesh.h:264
bool is_tracked_edge(const Tuple &e) const override
Definition TriOptimizerMesh.h:756
bool storage_grows_on_demand() const override
Definition TriOptimizerMesh.h:417
bool is_inverted(const std::array< size_t, 3 > &vs) const
Orientation check, exact for the coordinates the vertices actually carry.
Definition TriOptimizerMesh.cpp:485
AttributeContainerGroup m_face_attr_group
What p_face_attrs points at, so a derived class can register more.
Definition TriOptimizerMesh.h:161
static constexpr size_t NO_FEATURE_POINT
A vertex that stands for no feature point. See FeaturePointAttributes.
Definition TriOptimizerMesh.h:235
optimization::SmoothRejectCounters m_smooth_rejects
Why smoothing attempts were refused, reported once per pass.
Definition TriOptimizerMesh.h:189
OptimizerParameters & m_params
Definition TriOptimizerMesh.h:175
std::string m_debug_pass_name
Definition TriOptimizerMesh.h:197
double m_s_amips
Definition TriOptimizerMesh.h:182
bool swap_edge_after(const Tuple &t) override
User specified modifications and desideras after an edge swap.
Definition TriOptimizerMesh.cpp:362
bool collapse_edge_after(const Tuple &t) override
User specified modifications and desideratas after an edge collapse.
Definition TriOptimizerMeshCollapse.cpp:348
bool round_vertex(const size_t vid) override
Definition TriOptimizerMesh.h:750
bool round(const Tuple &v)
Round a vertex position to floating point, if that inverts no incident face.
Definition TriOptimizerMesh.cpp:536
virtual bool optimization_bare_coarsen_passes() const
Whether the loop opens and closes with BARE collapse passes.
Definition TriOptimizerMesh.h:660
void throw_if_in_operation_pass(const char *call) const
Definition TriOptimizerMesh.h:288
int m_iterations_used
Shared TriWild/SimWild outer optimization schedule.
Definition TriOptimizerMesh.h:402
FeaturePointAttCol m_feature_point_attribute
Registered with m_vertex_attr_group only once enable_feature_point_tracking() ran.
Definition TriOptimizerMesh.h:243
virtual std::shared_ptr< Envelope > surface_envelope_for_edge(const std::array< size_t, 2 > &vids, const EdgeAttributes &attr) const
Envelope the tracked-surface segment vids must stay inside, given the attributes attr it carries – or...
Definition TriOptimizerMesh.h:822
bool split_edge_after(const Tuple &loc) override
User specified modifications and desideratas after an edge split.
Definition TriOptimizerMeshSplit.cpp:223
double region_max_quality_rel(const std::vector< size_t > &vids) const
Definition TriOptimizerMeshCollapse.cpp:495
std::pair< size_t, size_t > feature_retention(double *worst_ratio=nullptr) const
{feature points still represented within m_feature_eps, total feature points}.
Definition TriOptimizerMesh.cpp:814
std::atomic< size_t > m_feature_rejects
Definition TriOptimizerMesh.h:269
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:592
virtual std::tuple< double, double > optimization_quality_stats()
Definition TriOptimizerMesh.cpp:30
bool split_edge_before(const Tuple &t) override
User specified preparations and desideratas for an edge split.
Definition TriOptimizerMeshSplit.cpp:150
virtual std::shared_ptr< Envelope > smoothing_containment_envelope(const size_t, const std::array< size_t, 2 > &edge, const EdgeAttributes &attr) const
Definition TriOptimizerMesh.h:572
virtual void optimization_debug_checkpoint()
Called at every pass boundary, whether or not debug output is on.
Definition TriOptimizerMesh.h:704
bool split_edge_is_due(const Tuple &e) const
Definition TriOptimizerMeshSplit.cpp:134
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:113
uint32_t m_op_epoch
Definition TriOptimizerMesh.h:666
bool m_tracks_orientation
The application set EdgeAttributes::m_orientation at insertion, so the tracked curves carry the input...
Definition TriOptimizerMesh.h:114
std::vector< Vector2d > m_feature_points
Definition TriOptimizerMesh.h:249
virtual void update_attributes()
Update the attributes of the mesh after an iteration of operations.
Definition TriOptimizerMesh.h:399
double m_feature_eps
Definition TriOptimizerMesh.h:262
bool smooth_before(const Tuple &t) override
The smoothing hooks. A derived class overriding them – or invariants(), which a smooth also runs – mu...
Definition TriOptimizerMeshSmooth.cpp:15
Definition Simplex.hpp:46
Definition enumerable_thread_specific.hpp:37
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:908
What coarsen_mesh() achieved, for the run report. Zeroed when the pass is off.
Definition TriOptimizerMesh.h:481
Definition TriOptimizerMesh.h:866
std::vector< std::pair< std::array< size_t, 2 >, EdgeAttributes > > surface_edges
Definition TriOptimizerMesh.h:875
std::vector< std::pair< std::array< size_t, 2 >, int > > renamed_orientations
Definition TriOptimizerMesh.h:878
double region_max_rel_before
Definition TriOptimizerMesh.h:883
Definition TriOptimizerMesh.h:95
Definition TriOptimizerMesh.h:237
size_t m_feature_point_id
Index into m_feature_points, or NO_FEATURE_POINT.
Definition TriOptimizerMesh.h:239
Definition TriOptimizerMesh.h:856
Definition TriOptimizerMesh.h:892
Definition TriOptimizerMesh.h:45
bool m_is_rounded
Definition TriOptimizerMesh.h:52
A complex and the edits it went through, in commit order.
Definition History.hpp:101
Why a smoothing attempt was refused, counted per pass.
Definition SmoothVertex.hpp:32