31 inline const std::array<edge_bitset, 14> NeighborMasks{0x321a, 0x2015, 0x24b2, 0x0251, 0x006f,
39 std::optional<double> value_;
44 edge_bitset intersections_{};
47 edge_bitset all_intersections_{};
49 std::unique_ptr<std::vector<vertex_index>> vis_;
51 std::unique_ptr<std::array<rmt_node*, 14>> neighbors_;
53 static std::vector<edge_bitset> connected_components(edge_bitset edge_set) {
54 std::vector<edge_bitset> components;
55 while (edge_set != 0) {
56 edge_bitset component{};
57 edge_bitset queue = 1 << bit_peek(edge_set);
59 auto e = bit_pop(&queue);
62 queue |= NeighborMasks.at(e) & edge_set;
64 components.push_back(component);
72 void cluster(std::vector<geometry::point3d>& vertices,
73 std::unordered_map<vertex_index, vertex_index>& cluster_map)
const {
74 auto surfaces = connected_components(intersections_);
76 auto holes = connected_components(
surface ^ EdgeSetMask);
77 if (holes.size() != 1) {
84 auto new_vi =
static_cast<vertex_index
>(vertices.size());
88 auto edge_idx = bit_pop(&
surface);
89 auto vi = vertex_on_edge(edge_idx);
90 clustered += vertices.at(vi);
91 cluster_map.emplace(vi, new_vi);
93 clustered /=
static_cast<double>(n);
95 vertices.push_back(clustered);
99 bool has_intersection(edge_index edge_idx)
const {
100 edge_bitset edge_bit = 1 << edge_idx;
101 return (intersections_ & edge_bit) != 0;
104 bool has_neighbor(edge_index edge)
const {
return neighbors_->at(edge) !=
nullptr; }
106 void insert_vertex(vertex_index vi, edge_index edge_idx) {
107 RSMESH_ASSERT(!has_intersection(edge_idx));
110 vis_ = std::make_unique<std::vector<vertex_index>>();
113 edge_bitset edge_bit = 1 << edge_idx;
114 edge_bitset edge_count_mask = edge_bit - 1;
116 intersections_ |= edge_bit;
118 auto it = vis_->begin() + bit_count(
static_cast<edge_bitset
>(intersections_ & edge_count_mask));
119 vis_->insert(it, vi);
121 RSMESH_ASSERT(vertex_on_edge(edge_idx) == vi);
124 bool is_free()
const {
return all_intersections_ == 0; }
126 rmt_node& neighbor(edge_index edge) {
127 RSMESH_ASSERT(has_neighbor(edge));
128 return *neighbors_->at(edge);
131 const rmt_node& neighbor(edge_index edge)
const {
132 RSMESH_ASSERT(has_neighbor(edge));
133 return *neighbors_->at(edge);
138 void set_intersection(edge_index edge_idx) {
139 edge_bitset edge_bit = 1 << edge_idx;
141 all_intersections_ |= edge_bit;
144 void set_neighbors(std::unique_ptr<std::array<rmt_node*, 14>> neighbors) {
145 neighbors_.swap(neighbors);
148 void set_value(
double value) {
149 RSMESH_ASSERT(!value_.has_value());
153 double value()
const {
154 RSMESH_ASSERT(value_.has_value());
158 binary_sign value_sign()
const {
return value() < 0 ? Neg : Pos; }
160 vertex_index vertex_on_edge(edge_index edge_idx)
const {
161 RSMESH_ASSERT(has_intersection(edge_idx));
163 edge_bitset edge_bit = 1 << edge_idx;
164 edge_bitset edge_count_mask = edge_bit - 1;
165 return vis_->at(bit_count(
static_cast<edge_bitset
>(intersections_ & edge_count_mask)));