mirror of https://github.com/CGAL/cgal
rewrite/refactor a lot of the code
This commit is contained in:
parent
cf815b823f
commit
1ce108778f
|
|
@ -36,6 +36,9 @@ namespace internal {
|
|||
// when T does not have a Has_timestamp tag
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_timestamp_v = Has_timestamp<T>::value;
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace CGAL
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,19 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <class Func>
|
||||
class Output_rep<Func, IO_manip_tag>
|
||||
{
|
||||
Func f;
|
||||
|
||||
public:
|
||||
Output_rep(Func f) : f(f) {}
|
||||
std::ostream& operator()(std::ostream& os) const
|
||||
{
|
||||
return f(os);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\relates Output_rep
|
||||
\brief stream output of the \c Output_rep calls its \c operator().
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ template<> struct Io_traits<float> { typedef io_Read_write Io_tag; };
|
|||
template<> struct Io_traits<double> { typedef io_Read_write Io_tag; };
|
||||
template<> struct Io_traits<long double> { typedef io_Read_write Io_tag; };
|
||||
|
||||
|
||||
struct IO_manip_tag{};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
|
|
|
|||
|
|
@ -378,57 +378,69 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Removes pos from the constraint cid.
|
||||
// Returns the iterator to vertex that was just after pos (or end())
|
||||
// Writes the modified faces to out
|
||||
template <class OutputIterator>
|
||||
Vertices_in_constraint_iterator
|
||||
remove_vertex_from_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos,
|
||||
OutputIterator out)
|
||||
{
|
||||
if(pos == vertices_in_constraint_begin(cid)){
|
||||
++pos;
|
||||
Constraint_id aux = hierarchy.split2(cid,pos);
|
||||
// cid is [P, A, ..., B] -> split to aux=[P, A] and cid=[A...B]
|
||||
Constraint_id aux = hierarchy.split2(cid, std::next(pos));
|
||||
remove_constraint(aux, out);
|
||||
return pos;
|
||||
return vertices_in_constraint_begin(cid);
|
||||
}
|
||||
|
||||
Vertices_in_constraint_iterator it = vertices_in_constraint_end(cid);
|
||||
it--;
|
||||
if(pos == it){
|
||||
--pos;
|
||||
Constraint_id aux = hierarchy.split(cid, pos);
|
||||
if(pos == std::prev(vertices_in_constraint_end(cid))){
|
||||
// cid is [A, ..., B, P] -> split to cid=[A...B] and aux=[B,P]
|
||||
Constraint_id aux = hierarchy.split(cid, std::prev(pos));
|
||||
remove_constraint(aux, out);
|
||||
return vertices_in_constraint_end(cid);
|
||||
}
|
||||
|
||||
Vertices_in_constraint_iterator pp = pos;
|
||||
--pp;
|
||||
Vertex_handle a = *pp;
|
||||
pp = pos;
|
||||
++pp;
|
||||
Vertex_handle b = *pp;
|
||||
--it;
|
||||
Vertices_in_constraint_iterator beg = vertices_in_constraint_begin(cid);
|
||||
++beg;
|
||||
Face_container<Constrained_triangulation_plus_2> fc(*this);
|
||||
const auto second_vertex_of_cid = std::next(vertices_in_constraint_begin(cid));
|
||||
const auto next_to_last_vertex_of_cid = std::prev(vertices_in_constraint_end(cid), 2);
|
||||
|
||||
Constraint_id head = nullptr, tail = nullptr;
|
||||
if(pos != beg){
|
||||
if(pos != second_vertex_of_cid){
|
||||
// cid is [A, ..., B, P, C, ..., D]
|
||||
// split to:
|
||||
// head = [A...B] and,
|
||||
// cid = [B, P, C...D]
|
||||
// split off head
|
||||
--pos;
|
||||
head = hierarchy.split2(cid, pos);
|
||||
++pos;
|
||||
head = hierarchy.split2(cid, std::prev(pos));
|
||||
}
|
||||
if(pos != it){
|
||||
if(pos != next_to_last_vertex_of_cid){
|
||||
// cid is now [B, P, C, ..., D]
|
||||
// split to:
|
||||
// cid = [B, P, C] and,
|
||||
// tail = [C...D]
|
||||
// split off tail
|
||||
++pos;
|
||||
tail = hierarchy.split(cid,pos);
|
||||
tail = hierarchy.split(cid,std::next(pos));
|
||||
}
|
||||
|
||||
Constraint_id aux = insert_constraint(a, b, std::back_inserter(fc));
|
||||
pos = vertices_in_constraint_end(aux);
|
||||
--pos;
|
||||
--pos; // this is not necessarily == vertices_in_constraint_begin(aux);
|
||||
// now:
|
||||
// cid is [B, P, C]
|
||||
// head is null or [A...B]
|
||||
// tail is null or [C...D]
|
||||
// Let create insert [C,D] and conditionnaly concatenate head and tail,
|
||||
// and return the iterator to C
|
||||
|
||||
Vertex_handle b = *std::prev(pos);
|
||||
Vertex_handle c = *std::next(pos);
|
||||
|
||||
Face_container<Constrained_triangulation_plus_2> fc(*this);
|
||||
Constraint_id aux = insert_constraint(b, c, std::back_inserter(fc));
|
||||
|
||||
auto pos_before_c = std::prev(vertices_in_constraint_end(aux), 2);
|
||||
// `pos_before_c` is not necessarily == vertices_in_constraint_begin(aux)
|
||||
// there might have been intersecting constraints
|
||||
|
||||
hierarchy.swap(cid, aux);
|
||||
remove_constraint(aux, std::back_inserter(fc));
|
||||
remove_constraint(aux, std::back_inserter(fc)); // removes [B, P, C]
|
||||
|
||||
if(head != nullptr){
|
||||
hierarchy.concatenate2(head, cid);
|
||||
|
|
@ -438,8 +450,9 @@ public:
|
|||
hierarchy.concatenate(cid, tail);
|
||||
}
|
||||
fc.write_faces(out);
|
||||
++pos; // we went one too far back because the last vertex gets removed by concatenate
|
||||
return pos;
|
||||
|
||||
// we went one too far back because the last vertex `c` gets removed by concatenate
|
||||
return std::next(pos_before_c);
|
||||
}
|
||||
|
||||
// Inserts vh before pos
|
||||
|
|
@ -461,61 +474,56 @@ public:
|
|||
// Insertion after the last vertex
|
||||
if(pos == vertices_in_constraint_end(cid)){
|
||||
//std::cout << "insertion after last vertex" << std::endl;
|
||||
pos--;
|
||||
Constraint_id tail = insert_constraint(*pos, vh, out);
|
||||
pos = vertices_in_constraint_end(tail);
|
||||
--pos;
|
||||
Constraint_id tail = insert_constraint(*std::prev(pos), vh, out);
|
||||
auto returned_pos = std::prev(vertices_in_constraint_end(tail));
|
||||
hierarchy.concatenate(cid, tail);
|
||||
return pos;
|
||||
return returned_pos;
|
||||
}
|
||||
Vertices_in_constraint_iterator pred = std::prev(pos);
|
||||
Vertices_in_constraint_iterator last = std::prev(vertices_in_constraint_end(cid));
|
||||
Vertex_handle a = *pred;
|
||||
Vertex_handle b = *pos;
|
||||
--pos;
|
||||
Vertex_handle a = *pos;
|
||||
++pos;
|
||||
|
||||
// cid is [..., A, B, ...] and M=*vh will be inserted between A and B
|
||||
|
||||
Face_container<Constrained_triangulation_plus_2> fc(*this);
|
||||
Vertices_in_constraint_iterator beg = vertices_in_constraint_begin(cid), vcit;
|
||||
++beg;
|
||||
vcit = beg;
|
||||
++beg;
|
||||
Constraint_id aux1 = insert_constraint(a, vh, std::back_inserter(fc));
|
||||
Constraint_id aux2 = insert_constraint(vh, b, std::back_inserter(fc));
|
||||
auto returned_pos = vertices_in_constraint_begin(aux2);
|
||||
concatenate(aux1, aux2);
|
||||
// here:
|
||||
// aux1 is [A, M, B]
|
||||
// aux2 is empty
|
||||
// and returned_pos is the iterator to M
|
||||
|
||||
const auto second_vertex_of_cid = std::next(vertices_in_constraint_begin(cid));
|
||||
// If the constraint consists only of a segment, and we want to insert
|
||||
// in the middle
|
||||
if((pos == vcit) && (beg == vertices_in_constraint_end(cid))){
|
||||
// in the middle: cid is just the segment [A, B]
|
||||
if((pos == second_vertex_of_cid) && (second_vertex_of_cid == last)){
|
||||
//std::cout << "insertion in constraint which is a segment" << std::endl;
|
||||
Constraint_id aux1 = insert_constraint(a, vh, std::back_inserter(fc));
|
||||
Constraint_id aux2 = insert_constraint(vh, b, std::back_inserter(fc));
|
||||
pos = vertices_in_constraint_begin(aux2);
|
||||
concatenate(aux1, aux2);
|
||||
hierarchy.swap(cid, aux1);
|
||||
remove_constraint(aux1, std::back_inserter(fc));
|
||||
fc.write_faces(out);
|
||||
return pos;
|
||||
|
||||
return returned_pos;
|
||||
}
|
||||
|
||||
Constraint_id head = nullptr, tail = nullptr;
|
||||
Vertices_in_constraint_iterator bit = vertices_in_constraint_begin(cid);
|
||||
Vertices_in_constraint_iterator pred = pos;
|
||||
--pred;
|
||||
++bit;
|
||||
if(pos != bit){
|
||||
if(pos != second_vertex_of_cid){
|
||||
//std::cout << "split head" << std::endl;
|
||||
head = split(cid, pred);
|
||||
std::swap(head,cid); // split2 does the job
|
||||
pred = vertices_in_constraint_begin(cid);
|
||||
pos = pred;
|
||||
++pos;
|
||||
pos = std::next(pred);
|
||||
}
|
||||
Vertices_in_constraint_iterator eit = vertices_in_constraint_end(cid);
|
||||
--eit;
|
||||
if(pos != eit){
|
||||
// head is now [..., A] or null
|
||||
// cid is now [A, B, ...]
|
||||
if(pos != last){
|
||||
//std::cout << "split tail" << std::endl;
|
||||
tail = split(cid, pos);
|
||||
}
|
||||
|
||||
// make the new constraint
|
||||
Constraint_id aux1 = insert_constraint(a, vh, std::back_inserter(fc));
|
||||
Constraint_id aux2 = insert_constraint(vh, b, std::back_inserter(fc));
|
||||
pos = vertices_in_constraint_begin(aux2);
|
||||
concatenate(aux1, aux2);
|
||||
// head is now [..., A] or null
|
||||
// cid is now [A, B]
|
||||
// tail is now [B, ...] or null
|
||||
|
||||
if(head != nullptr){
|
||||
//std::cout << "concatenate head" << std::endl;
|
||||
|
|
@ -988,7 +996,7 @@ insert_subconstraint(Vertex_handle vaa,
|
|||
|
||||
//to debug
|
||||
public:
|
||||
void print_hierarchy() { hierarchy.print(); }
|
||||
void print_hierarchy(std::ostream& os = std::cout) { hierarchy.print(os); }
|
||||
|
||||
//template member functions
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include <CGAL/Skiplist.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
#include <CGAL/IO/io.h>
|
||||
|
||||
#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS
|
||||
# include <CGAL/IO/io.h>
|
||||
|
|
@ -62,7 +64,6 @@ private:
|
|||
private:
|
||||
Vertex_handle vertex_;
|
||||
Point point_;
|
||||
public:
|
||||
bool input_;
|
||||
};
|
||||
|
||||
|
|
@ -213,6 +214,7 @@ public:
|
|||
typedef typename Constraints_set::iterator Constraint_iterator;
|
||||
typedef const Constraints_set& Constraints;
|
||||
typedef typename Sc_to_c_map::const_iterator Sc_iterator;
|
||||
typedef typename Sc_to_c_map::iterator Sc_it;
|
||||
typedef Sc_iterator Subconstraint_and_contexts_iterator;
|
||||
typedef const Sc_to_c_map& Subconstraints_and_contexts;
|
||||
|
||||
|
|
@ -447,7 +449,53 @@ public:
|
|||
void swap(Polyline_constraint_hierarchy_2& ch);
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
void for_context_lists_of_all_subconstraints(Constraint_id cid, const F& f)
|
||||
{
|
||||
auto vl = cid.vl_ptr();
|
||||
for(Vertex_it it = vl->skip_begin(), succ = it, end = vl->skip_end(); ++succ != end; ++it) {
|
||||
auto scit = sc_to_c_map.find(sorted_pair(*it, *succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
f(hcl, it, scit);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_first_in_context_list(Context_list* hcl, Constraint_id old_id, Constraint_id new_id)
|
||||
{
|
||||
// std::find_if is a sort of std::for_each with a break
|
||||
[[maybe_unused]] auto it = std::find_if(hcl->begin(), hcl->end(), [&](Context& ctxt) {
|
||||
if(ctxt.enclosing == old_id) {
|
||||
ctxt.enclosing = new_id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
static void update_first_context_position(Context_list* hcl, Constraint_id id, Vertex_it new_pos)
|
||||
{
|
||||
[[maybe_unused]] auto it = std::find_if(hcl->begin(), hcl->end(), [&](Context& ctxt) {
|
||||
if(ctxt.enclosing == id) {
|
||||
ctxt.pos = new_pos;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
static void remove_first_in_context_list(Context_list* hcl, Constraint_id id)
|
||||
{
|
||||
auto it = std::find_if(hcl->begin(), hcl->end(), [&](Context& ctxt) {
|
||||
return ctxt.enclosing == id;
|
||||
});
|
||||
if(it != hcl->end()) {
|
||||
hcl->erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
Constraint_id new_constraint_id() const {
|
||||
// TODO: handle ids
|
||||
auto id = number_of_constraints() == 0 ? 0 : constraints_set.rbegin()->id + 1;
|
||||
return Constraint_id(new Vertex_list, id);
|
||||
}
|
||||
|
|
@ -464,7 +512,7 @@ private:
|
|||
|
||||
//to_debug
|
||||
public:
|
||||
void print() const;
|
||||
void print(std::ostream& os = std::cout) const;
|
||||
};
|
||||
|
||||
template <class T, class Compare, class Point>
|
||||
|
|
@ -645,29 +693,18 @@ template <class T, class Compare, class Point>
|
|||
void
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::
|
||||
swap(Constraint_id constr_a, Constraint_id constr_b) {
|
||||
auto substitute_enclosing_in_vertex_list = [this](Vertex_list_ptr vl, Constraint_id old_id, Constraint_id new_id) {
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = vl->skip_begin(), succ = it, end = vl->skip_end(); ++succ != end; ++it) {
|
||||
typename Sc_to_c_map::iterator scit = this->sc_to_c_map.find(sorted_pair(*it, *succ));
|
||||
CGAL_assertion(scit != this->sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
|
||||
// and replace the context of the constraint
|
||||
for(Context_iterator ctit = hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == old_id) {
|
||||
ctit->enclosing = new_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto substitute_enclosing_in_vertex_list = [this](Constraint_id cid, Constraint_id old_id, Constraint_id new_id) {
|
||||
for_context_lists_of_all_subconstraints(cid, [&](Context_list* hcl, Vertex_it, Sc_it) {
|
||||
replace_first_in_context_list(hcl, old_id, new_id);
|
||||
});
|
||||
};
|
||||
|
||||
Vertex_list_ptr constr_a_vl = constr_a.vl_ptr();
|
||||
Vertex_list_ptr constr_b_vl = constr_b.vl_ptr();
|
||||
|
||||
substitute_enclosing_in_vertex_list(constr_a_vl, constr_a, nullptr);
|
||||
substitute_enclosing_in_vertex_list(constr_b_vl, constr_b, constr_a);
|
||||
substitute_enclosing_in_vertex_list(constr_a_vl, nullptr, constr_b);
|
||||
substitute_enclosing_in_vertex_list(constr_a, constr_a, nullptr);
|
||||
substitute_enclosing_in_vertex_list(constr_b, constr_b, constr_a);
|
||||
substitute_enclosing_in_vertex_list(constr_a, nullptr, constr_b);
|
||||
|
||||
constr_a_vl->swap(*constr_b_vl);
|
||||
}
|
||||
|
|
@ -675,33 +712,22 @@ swap(Constraint_id constr_a, Constraint_id constr_b) {
|
|||
template <class T, class Compare, class Point>
|
||||
void
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::
|
||||
remove_constraint(Constraint_id cid){
|
||||
remove_constraint(Constraint_id cid)
|
||||
{
|
||||
constraints_set.erase(cid);
|
||||
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = cid.begin(), succ = it, end = cid.end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
for_context_lists_of_all_subconstraints(cid, [&](Context_list* hcl, Vertex_it, Sc_it scit) {
|
||||
remove_first_in_context_list(hcl, cid);
|
||||
|
||||
// and remove the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == cid){
|
||||
hcl->erase(ctit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the constraint passes several times through the same subconstraint,
|
||||
// the above loop maybe removes them in the wrong order
|
||||
// the above call to `remove_first_in_context_list` may remove them in the wrong order.
|
||||
|
||||
// If this was the only context in the list, delete the context list
|
||||
if(hcl->empty()){
|
||||
if(hcl->empty()) {
|
||||
sc_to_c_map.erase(scit);
|
||||
delete hcl;
|
||||
}
|
||||
}
|
||||
});
|
||||
delete cid.vl_ptr();
|
||||
}
|
||||
|
||||
|
|
@ -802,53 +828,31 @@ template <class T, class Compare, class Point>
|
|||
typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate(Constraint_id constr_a, Constraint_id constr_b)
|
||||
{
|
||||
// constr_a is [A, ..., M]
|
||||
// constr_b is [M, ..., B]
|
||||
// we want:
|
||||
// constr_a = [A, ..., M, ..., B]
|
||||
// constr_b = []
|
||||
|
||||
// std::cerr << std::format("concatenate({}, {}) ", constr_a.id, constr_b.id) << std::endl;
|
||||
Vertex_list_ptr constr_a_vl = constr_a.vl_ptr();
|
||||
Vertex_list_ptr constr_b_vl = constr_b.vl_ptr();
|
||||
constraints_set.erase(constr_a);
|
||||
constraints_set.erase(constr_b);
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = constr_b_vl->skip_end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
|
||||
// and replace the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr_b){
|
||||
ctit->enclosing = constr_a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for_context_lists_of_all_subconstraints(constr_b, [&](Context_list* hcl, Vertex_it, Sc_it) {
|
||||
replace_first_in_context_list(hcl, constr_b, constr_a);
|
||||
});
|
||||
|
||||
// now we really concatenate the vertex lists
|
||||
// Note that all iterators pointing into constr_a remain valid.
|
||||
// This concerns user code, as well as the data member "pos" of the Context class
|
||||
CGAL_assertion(constr_a_vl->back().vertex() == constr_b_vl->front().vertex());
|
||||
constr_a_vl->pop_back(); // because it is the same as constr_b_vl.front()
|
||||
Vertex_it back_it = constr_a_vl->skip_end();
|
||||
--back_it;
|
||||
constr_a_vl->splice(constr_a_vl->skip_end(), *(constr_b_vl), constr_b_vl->skip_begin(), constr_b_vl->skip_end());
|
||||
constr_a_vl->splice(constr_a_vl->skip_end(), *constr_b_vl, constr_b_vl->skip_begin(), constr_b_vl->skip_end());
|
||||
|
||||
// Note that for VC8 with iterator debugging the iterators pointing into constr_b
|
||||
// are NOT valid So we have to update them
|
||||
for(Vertex_it it = back_it, succ = it, end = constr_a_vl->skip_end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
|
||||
// and update pos in the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr_a){
|
||||
ctit->pos = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
constraints_set.insert(constr_a);
|
||||
for_context_lists_of_all_subconstraints(constr_a, [&](Context_list* hcl, Vertex_it it, Sc_it) {
|
||||
update_first_context_position(hcl, constr_a, it);
|
||||
});
|
||||
|
||||
delete constr_b_vl;
|
||||
return constr_a;
|
||||
|
|
@ -858,54 +862,34 @@ template <class T, class Compare, class Point>
|
|||
typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate2(Constraint_id constr_a, Constraint_id constr_b)
|
||||
{
|
||||
// constr_a is [A, ..., M]
|
||||
// constr_b is [M, ..., B]
|
||||
// we want:
|
||||
// constr_a =
|
||||
// constr_b = [A, ..., M, ..., B]
|
||||
|
||||
Vertex_list_ptr constr_a_vl = constr_a.vl_ptr();
|
||||
Vertex_list_ptr constr_b_vl = constr_b.vl_ptr();
|
||||
constraints_set.erase(constr_a);
|
||||
constraints_set.erase(constr_b);
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = constr_a_vl->skip_begin(), succ = it, end = constr_a_vl->skip_end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
constraints_set.erase(constr_a); // DIFF
|
||||
|
||||
for_context_lists_of_all_subconstraints(constr_a, [&](Context_list* hcl, Vertex_it, Sc_it) { // DIFF
|
||||
replace_first_in_context_list(hcl, constr_a, constr_b); // DIFF
|
||||
});
|
||||
|
||||
// and replace the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr_a){
|
||||
ctit->enclosing = constr_b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// now we really concatenate the vertex lists
|
||||
// Note that all iterators pointing into constr_b remain valid.
|
||||
CGAL_assertion(constr_a_vl->back().vertex() == constr_b_vl->front().vertex());
|
||||
constr_a_vl->pop_back(); // because it is the same as constr_b_vl.front()
|
||||
Vertex_it back_it = constr_b_vl->skip_begin();
|
||||
|
||||
constr_b_vl->splice(constr_b_vl->skip_begin(), *(constr_a_vl), constr_a_vl->skip_begin(), constr_a_vl->skip_end());
|
||||
constr_b_vl->splice(constr_b_vl->skip_begin(), *constr_a_vl, constr_a_vl->skip_begin(), constr_a_vl->skip_end()); // DIFF
|
||||
|
||||
// Note that for VC8 with iterator debugging the iterators pointing into constr_a
|
||||
// are NOT valid So we have to update them
|
||||
for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = back_it;
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
for_context_lists_of_all_subconstraints(constr_b /*DIFF*/, [&](Context_list* hcl, Vertex_it it, Sc_it) {
|
||||
update_first_context_position(hcl, constr_b, it); // DIFF
|
||||
});
|
||||
|
||||
// and update pos in the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr_b){
|
||||
ctit->pos = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
constraints_set.insert(constr_b);
|
||||
|
||||
delete constr_a_vl;
|
||||
return constr_b;
|
||||
delete constr_a_vl; // DIFF
|
||||
return constr_b; // DIFF
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -916,35 +900,35 @@ template <class T, class Compare, class Point>
|
|||
typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::split(Constraint_id constr, Vertex_it vcit)
|
||||
{
|
||||
Constraint_id new_constr = new_constraint_id();
|
||||
constraints_set.erase(constr);
|
||||
Vertex_list_ptr new_vl = new_constr.vl_ptr();
|
||||
Vertex_list_ptr constr_vl = constr.vl_ptr();
|
||||
new_vl->splice(new_vl->skip_end(), *(constr_vl), vcit.base(), constr_vl->skip_end());
|
||||
constr_vl->push_back(new_vl->front()); // Duplicate the common vertex
|
||||
Vertex_it vit = new_vl->skip_begin();
|
||||
vit.input() = true;
|
||||
vit = constr_vl->skip_end();
|
||||
--vit;
|
||||
vit.input() = true;
|
||||
constraints_set.insert(constr);
|
||||
constraints_set.insert(new_constr);
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
// constr is [A, ..., B], vcit points to M in [A, ..., B]
|
||||
|
||||
Constraint_id new_constr = new_constraint_id();
|
||||
constraints_set.insert(new_constr);
|
||||
|
||||
Vertex_list_ptr constr_vl = constr.vl_ptr();
|
||||
Vertex_list_ptr new_vl = new_constr.vl_ptr();
|
||||
|
||||
vcit.input() = true;
|
||||
auto middle_node = Node(*vcit, true);
|
||||
|
||||
// Let's split, that way:
|
||||
// constr = [A, ..., M]
|
||||
// new_constr = [M, ..., B]
|
||||
|
||||
// The splice does:
|
||||
// constr = [A, ..., M[ (without M)
|
||||
// new_constr = [M, ..., B]
|
||||
new_vl->splice(new_vl->skip_end(), *constr_vl, vcit.base(), constr_vl->skip_end());
|
||||
constr_vl->push_back(middle_node); // add M to the end of constr
|
||||
|
||||
CGAL_assertion(vcit.base() == new_vl->skip_begin());
|
||||
CGAL_assertion(new_vl->front().input() == true);
|
||||
CGAL_assertion(constr_vl->back().input() == true);
|
||||
|
||||
for_context_lists_of_all_subconstraints(new_constr, [&](Context_list* hcl, Vertex_it, Sc_it) {
|
||||
replace_first_in_context_list(hcl, constr, new_constr);
|
||||
});
|
||||
|
||||
// and replace the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr){
|
||||
ctit->enclosing = new_constr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_constr;
|
||||
}
|
||||
|
||||
|
|
@ -952,35 +936,35 @@ template <class T, class Compare, class Point>
|
|||
typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::split2(Constraint_id constr, Vertex_it vcit)
|
||||
{
|
||||
Constraint_id new_constr = new_constraint_id();
|
||||
constraints_set.erase(constr);
|
||||
Vertex_list_ptr new_vl = new_constr.vl_ptr();
|
||||
Vertex_list_ptr constr_vl = constr.vl_ptr();
|
||||
new_vl->splice(new_vl->skip_end(), *constr_vl, constr_vl->skip_begin(), vcit.base());
|
||||
new_vl->push_back(constr_vl->front()); // Duplicate the common vertex
|
||||
Vertex_it vit = new_vl->skip_end();
|
||||
--vit;
|
||||
vit.input() = true;
|
||||
vit = constr_vl->skip_begin();
|
||||
vit.input() = true;
|
||||
constraints_set.insert(constr);
|
||||
constraints_set.insert(new_constr);
|
||||
// We have to look at all subconstraints
|
||||
for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end();
|
||||
++succ != end;
|
||||
++it){
|
||||
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
|
||||
CGAL_assertion(scit != sc_to_c_map.end());
|
||||
Context_list* hcl = scit->second;
|
||||
// constr is [A, ..., B], vcit points to M in [A, ..., B]
|
||||
|
||||
Constraint_id new_constr = new_constraint_id();
|
||||
constraints_set.insert(new_constr);
|
||||
|
||||
Vertex_list_ptr constr_vl = constr.vl_ptr();
|
||||
Vertex_list_ptr new_vl = new_constr.vl_ptr();
|
||||
|
||||
vcit.input() = true;
|
||||
auto middle_node = Node(*vcit, true);
|
||||
|
||||
// Let's split, that way:
|
||||
// constr = [M, ..., B]
|
||||
// new_constr = [A, ..., M]
|
||||
|
||||
// The splice does:
|
||||
// constr = [M, ..., B]
|
||||
// new_constr = [A, ..., M[ (without M)
|
||||
new_vl->splice(new_vl->skip_end(), *constr_vl, constr_vl->skip_begin(), vcit.base());
|
||||
new_vl->push_back(middle_node); // add M to the end of new_constr
|
||||
|
||||
CGAL_assertion(vcit.base() == constr_vl->skip_begin());
|
||||
CGAL_assertion(constr_vl->front().input() == true);
|
||||
CGAL_assertion(new_vl->back().input() == true);
|
||||
|
||||
for_context_lists_of_all_subconstraints(new_constr, [&](Context_list* hcl, Vertex_it, Sc_it) {
|
||||
replace_first_in_context_list(hcl, constr, new_constr);
|
||||
});
|
||||
|
||||
// and replace the context of the constraint
|
||||
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
|
||||
if(ctit->enclosing == constr){
|
||||
ctit->enclosing = new_constr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_constr;
|
||||
}
|
||||
|
||||
|
|
@ -1244,9 +1228,9 @@ oriented_end(T va, T vb, T& vc) const
|
|||
template <class T, class Compare, class Point>
|
||||
void
|
||||
Polyline_constraint_hierarchy_2<T,Compare,Point>::
|
||||
print() const
|
||||
print(std::ostream& os) const
|
||||
{
|
||||
std::map<T,int> vertex_num_map;
|
||||
std::map<Vertex_handle,int> vertex_num_map;
|
||||
int num = 0;
|
||||
for(const auto& cid : constraints()) {
|
||||
for (const auto& node : cid.elements()){
|
||||
|
|
@ -1254,51 +1238,51 @@ print() const
|
|||
}
|
||||
}
|
||||
|
||||
struct Vertex_num {
|
||||
std::map<T,int>& vertex_num_map;
|
||||
int operator[](T v) const {
|
||||
#ifndef CGAL_CDT_2_DEBUG_INTERSECTIONS
|
||||
auto it = vertex_num_map.find(v);
|
||||
if(it == vertex_num_map.end()) return -1;
|
||||
return it->second;
|
||||
#else
|
||||
return v->time_stamp();
|
||||
#endif
|
||||
}
|
||||
} vertex_num{vertex_num_map};
|
||||
// typename std::map<T,int>::iterator vnit = vertex_num.begin();
|
||||
// for(; vnit != vertex_num.end(); vnit++) {
|
||||
// vnit->second = ++num;
|
||||
// std::cerr << "vertex num " << num << " " << vnit->first->point()
|
||||
// << std::endl;
|
||||
// }
|
||||
auto disp_vertex = [&vertex_num_map](Vertex_handle v) {
|
||||
return CGAL::IO::oformat(
|
||||
[v, &vertex_num_map](auto& os) -> decltype(os)& {
|
||||
constexpr bool star_v_has_timestamp =
|
||||
internal::has_timestamp_v<CGAL::cpp20::remove_cvref_t<decltype(*v)>>;
|
||||
if constexpr(star_v_has_timestamp) {
|
||||
return os << '#' << v->time_stamp();
|
||||
} else {
|
||||
auto it = vertex_num_map.find(v);
|
||||
auto n = (it == vertex_num_map.end()) ? -1 : it->second;
|
||||
return os << n;
|
||||
}
|
||||
},
|
||||
IO_manip_tag{});
|
||||
};
|
||||
|
||||
os << "# number of constraints: " << number_of_constraints() << std::endl;
|
||||
for(const auto& cid : constraints()) {
|
||||
std::cout << std::endl;
|
||||
std::cout << "constraint(" << cid.id << ") ";
|
||||
std::cout << cid.vl_ptr();
|
||||
std::cout << " subconstraints ";
|
||||
os << "constraint(" << cid.id << ") ";
|
||||
os << cid.vl_ptr();
|
||||
os << "\n vertex list ";
|
||||
for(const auto& node : cid.elements()) {
|
||||
std::cout << vertex_num[node.vertex()] << " ";
|
||||
os << disp_vertex(node.vertex()) << " ";
|
||||
}
|
||||
std::cout << ": ";
|
||||
os << "\n corresponding points: ";
|
||||
for(const auto& node : cid.elements()) {
|
||||
std::cout << node.point() << " ";
|
||||
os << node.point() << " ";
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
os << std::endl;
|
||||
os << "# number of subconstraints: " << sc_to_c_map.size() << std::endl;
|
||||
for(const auto& subconstraint : subconstraints()) {
|
||||
std::cout << "subconstraint ";
|
||||
std::cout << vertex_num[subconstraint.first] << " " << vertex_num[subconstraint.second];
|
||||
os << "subconstraint (";
|
||||
os << disp_vertex(subconstraint.first) << ", "
|
||||
<< disp_vertex(subconstraint.second) << ")";
|
||||
Context_iterator cb, ce;
|
||||
get_contexts(subconstraint.first, subconstraint.second, cb, ce);
|
||||
|
||||
std::cout << " enclosing ";
|
||||
os << " enclosing: ";
|
||||
for(; cb != ce; cb++) {
|
||||
std::cout << "(" << cb->id().id << ") " << cb->id().vl_ptr();
|
||||
std::cout << " ";
|
||||
os << "(cid " << cb->id().id << ") " << cb->id().vl_ptr();
|
||||
os << ", pos: " << std::distance(cb->vertices_begin(), cb->pos) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
os << std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,89 +1,110 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Triangulation_2.h>
|
||||
// This code was first submitted in an issue:
|
||||
// https://github.com/CGAL/cgal/issues/4025
|
||||
// and then rewrote a lot, keeping the observed behavior.
|
||||
|
||||
#include <CGAL/Base_with_time_stamp.h>
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Constrained_triangulation_plus_2.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Polygon_2<K> Polygon_2;
|
||||
typedef CGAL::Exact_intersections_tag Itag_;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<K,CGAL::Default, Itag_> CDT;
|
||||
typedef CGAL::Constrained_triangulation_plus_2<CDT> CDTP;
|
||||
#include <string_view>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
typedef CDTP::Point Point;
|
||||
typedef CDTP::Constraint_id Cid;
|
||||
typedef CDTP::Vertex_handle Vertex_handle;
|
||||
typedef CDTP::Constraint_id Constraint_id;
|
||||
typedef CDTP::Vertices_in_constraint_iterator Vertices_in_constraint_iterator;
|
||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using Polygon_2 = CGAL::Polygon_2<K>;
|
||||
using Itag_ = CGAL::Exact_intersections_tag;
|
||||
using Vb = CGAL::Base_with_time_stamp<CGAL::Triangulation_vertex_base_2<K>>;
|
||||
using Cb = CGAL::Base_with_time_stamp<CGAL::Constrained_triangulation_face_base_2<K>>;
|
||||
using Tds = CGAL::Triangulation_data_structure_2<Vb, Cb>;
|
||||
using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag_>;
|
||||
using CDTP = CGAL::Constrained_triangulation_plus_2<CDT>;
|
||||
|
||||
int countVertex(CDTP &cdtp, CDTP::Constraint_id id)
|
||||
using Point = CDTP::Point;
|
||||
using Vertex_handle = CDTP::Vertex_handle;
|
||||
using Constraint_id = CDTP::Constraint_id;
|
||||
using Vertices_in_constraint_iterator = CDTP::Vertices_in_constraint_iterator;
|
||||
|
||||
auto nb_of_vertices(CDTP &cdtp, Constraint_id id)
|
||||
{
|
||||
Vertices_in_constraint_iterator v=cdtp.vertices_in_constraint_begin(id);
|
||||
|
||||
int count=0;
|
||||
while(v!=cdtp.vertices_in_constraint_end(id))
|
||||
{
|
||||
count++;
|
||||
v++;
|
||||
}
|
||||
|
||||
return count;
|
||||
return static_cast<std::size_t>(std::distance(cdtp.vertices_in_constraint_begin(id),
|
||||
cdtp.vertices_in_constraint_end(id)));
|
||||
}
|
||||
|
||||
auto value_check_expected =
|
||||
[](auto&& value, [[maybe_unused]] const auto& expected) -> decltype(auto)
|
||||
{
|
||||
assert(value == expected);
|
||||
return std::forward<decltype(value)>(value);
|
||||
};
|
||||
|
||||
auto oformat =
|
||||
[](Vertex_handle vh)
|
||||
{
|
||||
return CGAL::IO::oformat(vh, CGAL::With_point_tag{});
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
CDTP cdtp;
|
||||
|
||||
std::list<Point> pointsListCollinear;
|
||||
auto print_cdtp = [&cdtp](std::string_view msg)
|
||||
{
|
||||
std::cout << msg << std::endl;
|
||||
cdtp.print_hierarchy(std::cout);
|
||||
};
|
||||
|
||||
pointsListCollinear.push_back(Point(0,0));
|
||||
pointsListCollinear.push_back(Point(0,1));
|
||||
pointsListCollinear.push_back(Point(0,2));
|
||||
pointsListCollinear.push_back(Point(0,3));
|
||||
pointsListCollinear.push_back(Point(0,4));
|
||||
pointsListCollinear.push_back(Point(0,5));
|
||||
const std::array<Point, 6> collinear_points = {
|
||||
Point(0,0), Point(0,1), Point(0,2), Point(0,3), Point(0,4), Point(0,5)
|
||||
};
|
||||
|
||||
std::list<Point> pointsListNoCollinear;
|
||||
const std::array<Point, 6> non_collinear_points = {
|
||||
Point(1,0), Point(2,1), Point(4,2), Point(2,3), Point(4,4), Point(1,5)
|
||||
};
|
||||
|
||||
pointsListNoCollinear.push_back(Point(1,0));
|
||||
pointsListNoCollinear.push_back(Point(2,1));
|
||||
pointsListNoCollinear.push_back(Point(4,2));
|
||||
pointsListNoCollinear.push_back(Point(2,3));
|
||||
pointsListNoCollinear.push_back(Point(4,4));
|
||||
pointsListNoCollinear.push_back(Point(1,5));
|
||||
Constraint_id collinear_cid = cdtp.insert_constraint(collinear_points.begin(), collinear_points.end());
|
||||
Constraint_id non_collinear_cid = cdtp.insert_constraint(non_collinear_points.begin(), non_collinear_points.end());
|
||||
|
||||
print_cdtp("Initial state");
|
||||
|
||||
Constraint_id ctIdCollinear=cdtp.insert_constraint(pointsListCollinear.begin(),pointsListCollinear.end());
|
||||
Constraint_id ctIdNoCollinear=cdtp.insert_constraint(pointsListNoCollinear.begin(),pointsListNoCollinear.end());
|
||||
Vertices_in_constraint_iterator vertex_it = std::next(cdtp.vertices_in_constraint_begin(collinear_cid), 2);
|
||||
[[maybe_unused]] auto next_it = std::next(vertex_it);
|
||||
std::cout << "\n-> attempt to remove vertex " << oformat(*vertex_it) << std::endl;
|
||||
vertex_it = cdtp.remove_vertex_from_constraint(collinear_cid, vertex_it);
|
||||
std::cout << " cdtp.remove_vertex_from_constraint(collinear_cid, vertex_it) returned the vertex "
|
||||
<< oformat(*vertex_it) << std::endl;
|
||||
assert(vertex_it == next_it);
|
||||
|
||||
print_cdtp("\nAfter removing third vertex from the collinear constraint");
|
||||
|
||||
//******************************* attempt with the collinear constraint
|
||||
Vertices_in_constraint_iterator vertexToRemoveCollinear=cdtp.vertices_in_constraint_begin(ctIdCollinear);
|
||||
vertexToRemoveCollinear++;
|
||||
vertexToRemoveCollinear++;
|
||||
// The first constraint (ID `collinear_cid`) is collinear. `cdtp.remove_vertex_from_constraint`
|
||||
// cannot remove the third vertex from it, because it is collinear with the triangulation vertex
|
||||
// with the point (0, 2).
|
||||
|
||||
std::cout << "\nnumber of subconstraints: "
|
||||
<< value_check_expected(cdtp.number_of_subconstraints(), 10U) << std::endl;
|
||||
std::cout << "number of constraints: "
|
||||
<< value_check_expected(cdtp.number_of_constraints(), 2U) << std::endl;
|
||||
std::cout << "number of vertex in collinear constraint: "
|
||||
<< value_check_expected(nb_of_vertices(cdtp, collinear_cid), 6U) << std::endl;
|
||||
|
||||
std::cout<<"attempt to remove vertex "<<(*vertexToRemoveCollinear)->point().x()<<" , "<<(*vertexToRemoveCollinear)->point().y() <<std::endl;
|
||||
cdtp.remove_vertex_from_constraint(ctIdCollinear,vertexToRemoveCollinear);
|
||||
vertex_it = std::next(cdtp.vertices_in_constraint_begin(non_collinear_cid), 2);
|
||||
next_it = std::next(vertex_it);
|
||||
std::cout << "\n-> attempt to remove vertex " << oformat(*vertex_it) << std::endl;
|
||||
vertex_it = cdtp.remove_vertex_from_constraint(non_collinear_cid, vertex_it);
|
||||
std::cout << " cdtp.remove_vertex_from_constraint(non_collinear_cid, vertex_it) returned the vertex "
|
||||
<< oformat(*vertex_it) << std::endl;
|
||||
assert(vertex_it == next_it);
|
||||
|
||||
std::cout<<"number of subconstraints "<<cdtp.number_of_subconstraints()<<std::endl; //--> 5, expected 4
|
||||
std::cout<<"number of constraints "<<cdtp.number_of_constraints()<<std::endl; //--> 1
|
||||
std::cout<<"number of vertex in constraint "<<countVertex(cdtp,ctIdCollinear)<<std::endl; //--> 6, expected 5
|
||||
print_cdtp("\nAfter removing third vertex from the non-collinear constraint");
|
||||
|
||||
|
||||
//******************************* attempt with the collinear constraint
|
||||
Vertices_in_constraint_iterator vertexToRemoveNoCollinear=cdtp.vertices_in_constraint_begin(ctIdNoCollinear);
|
||||
vertexToRemoveNoCollinear++;
|
||||
vertexToRemoveNoCollinear++;
|
||||
|
||||
std::cout<<"attempt to remove vertex "<<(*vertexToRemoveNoCollinear)->point().x()<<" , "<<(*vertexToRemoveNoCollinear)->point().y() << std::endl;
|
||||
cdtp.remove_vertex_from_constraint(ctIdNoCollinear,vertexToRemoveNoCollinear);
|
||||
|
||||
std::cout<<"number of subconstraints "<<cdtp.number_of_subconstraints()<<std::endl; //--> 4, ok
|
||||
std::cout<<"number of constraints "<<cdtp.number_of_constraints()<<std::endl; //--> 1
|
||||
std::cout<<"number of vertex in constraint "<<countVertex(cdtp,ctIdNoCollinear)<<std::endl; //--> 5, ok
|
||||
std::cout << "number of subconstraints: "
|
||||
<< value_check_expected(cdtp.number_of_subconstraints(), 9U) << std::endl;
|
||||
std::cout << "number of constraints: "
|
||||
<< value_check_expected(cdtp.number_of_constraints(), 2U) << std::endl;
|
||||
std::cout << "number of vertex in collinear constraint: "
|
||||
<< value_check_expected(nb_of_vertices(cdtp, non_collinear_cid), 5U) << std::endl;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue