better handling of polygon vertices markers

This commit is contained in:
Laurent Rineau 2024-02-09 13:18:19 +01:00
parent a195631f1c
commit ba66191b30
2 changed files with 47 additions and 15 deletions

View File

@ -42,12 +42,19 @@ namespace CGAL {
enum class CDT_3_vertex_type { FREE, CORNER, STEINER_ON_EDGE, STEINER_IN_FACE };
enum class CDT_3_vertex_marker {
CLEAR = 0,
REGION_BORDER,
REGION_INSIDE,
nb_of_markers
};
using CDT_3_face_index = int; // must be signed
template <typename Gt, typename Vb = Triangulation_vertex_base_3<Gt> >
class Conforming_Delaunay_triangulation_vertex_base_3 : public Base_with_time_stamp<Vb> {
CDT_3_vertex_type m_vertex_type = CDT_3_vertex_type::FREE;
unsigned int mark = 0;
std::bitset<static_cast<int>(CDT_3_vertex_marker::nb_of_markers)> mark;
union U {
struct On_edge {
int nb_of_incident_constraints = 0;
@ -83,16 +90,20 @@ public:
return u.on_edge.nb_of_incident_constraints;
}
void mark_vertex() {
mark = 1;
void set_mark(CDT_3_vertex_marker marker) {
mark.set(static_cast<unsigned int>(marker));
}
void unmark_vertex() {
mark = 0;
void clear_marks() {
mark.reset();
}
bool is_marked() const {
return mark == 1;
void clear_mark(CDT_3_vertex_marker marker) {
mark.reset(static_cast<unsigned int>(marker));
}
bool is_marked(CDT_3_vertex_marker marker) const {
return mark.test(static_cast<unsigned int>(marker));
}
template<typename Triangulation>

View File

@ -218,6 +218,8 @@ public:
using Locate_type = typename T_3::Locate_type;
using Geom_traits = typename T_3::Geom_traits;
using Vertex_marker = CDT_3_vertex_marker;
using Face_index = CDT_3_face_index;
static std::string io_signature() {
@ -1026,8 +1028,8 @@ private:
{
const auto vc = cell->vertex(index_vd);
const auto vd = cell->vertex(index_vc);
if(!vd->is_Steiner_vertex_in_face() && vd->is_marked()) return 0; // vertex marked of the border
if(!vc->is_Steiner_vertex_in_face() && vc->is_marked()) return 0; // vertex marked of the border
if(vc->is_marked(Vertex_marker::REGION_BORDER)) return 0; // vertex marked of the border
if(vd->is_marked(Vertex_marker::REGION_BORDER)) return 0; // vertex marked of the border
const auto pc = this->point(vc);
const auto pd = this->point(vd);
const typename Geom_traits::Segment_3 seg{pc, pd};
@ -1200,10 +1202,10 @@ private:
#endif // CGAL_CDT_3_CAN_USE_CXX20_FORMAT
auto [cached_value_it, not_visited] = new_edge(v0, v1, false);
if(!not_visited) return value_returned(cached_value_it->second);
int v0v1_intersects_region = ((v0->is_Steiner_vertex_in_face() && v0->face_index() == face_index) ||
(v1->is_Steiner_vertex_in_face() && v1->face_index() == face_index))
? expected
: does_edge_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
int v0v1_intersects_region =
(v0->is_marked(Vertex_marker::REGION_INSIDE) || v1->is_marked(Vertex_marker::REGION_INSIDE))
? expected
: does_edge_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
if(v0v1_intersects_region != 0) {
if(v0v1_intersects_region != expected) {
throw PLC_error{"PLC error: v0v1_intersects_region != expected" ,
@ -1306,11 +1308,11 @@ private:
}
#endif // CGAL_CDT_3_CAN_USE_CXX20_FORMAT
for(auto v: region_border_vertices) {
v->mark_vertex();
v->set_mark(Vertex_marker::REGION_BORDER);
}
const auto found_edge_opt = search_first_intersection(face_index, cdt_2, fh_region, border_edges);
for(auto v: region_border_vertices) {
v->unmark_vertex();
v->clear_mark(Vertex_marker::REGION_BORDER);
}
[[maybe_unused]] auto try_flip_region_size_4 = [&] {
@ -1448,6 +1450,25 @@ private:
}
CGAL_assertion(found_edge_opt != std::nullopt);
for(auto v : region_border_vertices) {
v->set_mark(Vertex_marker::REGION_BORDER);
}
for(auto v : region_vertices) {
if(v->is_marked(Vertex_marker::REGION_BORDER))
continue;
v->set_mark(Vertex_marker::REGION_INSIDE);
}
struct Region_vertices_marker_scope_guard
{
std::function<void()> unmark;
~Region_vertices_marker_scope_guard() { unmark(); }
} guard{[&] {
for(auto v : region_vertices) {
v->clear_mark(Vertex_marker::REGION_BORDER);
v->clear_mark(Vertex_marker::REGION_INSIDE);
}
}};
const auto first_intersecting_edge = *found_edge_opt;
const auto [intersecting_edges, original_intersecting_cells, original_vertices_of_upper_cavity,
original_vertices_of_lower_cavity, original_facets_of_upper_cavity, original_facets_of_lower_cavity] =