3#include <wmtk/simplex/Simplex.hpp>
9#include <unordered_set>
13namespace wmtk::utils {
28using WorstCell = std::pair<double, size_t>;
42template <
class IsVal
id,
class Energy>
43std::vector<WorstCell> select_worst_cells(
51 std::vector<WorstCell> worst;
53 worst.reserve(num_worst);
56 for (
size_t cid = 0; cid < n_cells; ++cid) {
60 const double q = energy(cid);
61 if (q < filter_energy) {
65 if (
static_cast<int>(worst.size()) < num_worst) {
66 worst.emplace_back(q, cid);
67 std::sort(worst.begin(), worst.end());
68 }
else if (q > worst.front().first) {
69 worst.front() = {q, cid};
70 std::sort(worst.begin(), worst.end());
73 worst.emplace_back(q, cid);
78 std::sort(worst.begin(), worst.end());
93template <
size_t N,
class Pos>
94simplex::Edge longest_edge(
const std::array<size_t, N>& vs, Pos pos)
96 static_assert(N >= 2,
"a cell needs at least two vertices to have an edge");
100 for (
size_t a = 0; a < N; ++a) {
101 for (
size_t b = a + 1; b < N; ++b) {
102 const double l2 = (pos(vs[a]) - pos(vs[b])).squaredNorm();
110 return simplex::Edge(ea, eb);
119template <
class OneRing>
120std::unordered_set<size_t>
121grow_vertex_region(
const std::vector<size_t>& seeds,
int n_rings, OneRing one_ring)
123 std::unordered_set<size_t> region(seeds.begin(), seeds.end());
124 std::vector<size_t> frontier(region.begin(), region.end());
126 for (
int r = 0; r < n_rings; ++r) {
127 std::vector<size_t> next;
128 for (
const size_t v : frontier) {
129 for (
const size_t u : one_ring(v)) {
130 if (region.insert(u).second) {
146template <
class Sizing>
147std::vector<size_t> apply_sizing_refinement(
148 const std::unordered_set<size_t>& region,
153 std::vector<size_t> refined;
154 refined.reserve(region.size());
155 for (
const size_t v : region) {
156 double& s = sizing(v);
157 const double ns = std::max(floor, s * factor);
160 refined.push_back(v);
177template <
class Sizing,
class OneRing>
178void gradation_smooth_sizing(
180 const std::vector<size_t>& seeds,
188 std::queue<size_t> q;
189 for (
const size_t v : seeds) {
193 const size_t u = q.front();
195 const double cap = grade * sizing(u);
199 for (
const size_t w : one_ring(u)) {
200 double& sw = sizing(w);
233template <
class IsVal
id,
class Quality,
class CellV
ids,
class IsSurfaceVertex>
234std::vector<size_t> active_vertices(
241 IsSurfaceVertex is_surface_vertex)
243 std::vector<char> seen(n_verts, 0);
244 std::vector<size_t> out;
245 for (
size_t cid = 0; cid < n_cells; ++cid) {
246 if (!is_valid(cid)) {
249 if (quality(cid) < thr) {
252 for (
const size_t v : cell_vids(cid)) {
259 for (
size_t v = 0; v < n_verts; ++v) {
260 if (!seen[v] && is_surface_vertex(v)) {