1. Added additional flag in a halfedge, to indicate whether its target and face

have equal surface (i.e., are continuous) on the envelope.
This enables the removal of comparison between lists of surfaces, thus
the removal of "operator < for xy-monotone surface" from the traits concept
(when not using any cache).

2. Some cosmetic changes: improved remarks, removed Envelope_base class,
introduced caching traits.
This commit is contained in:
Michal Meyerovitch 2006-02-26 08:03:59 +00:00
parent 2b2f753289
commit 0cea00688d
1 changed files with 204 additions and 151 deletions

View File

@ -11,9 +11,9 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $Source: /CVSROOT/CGAL/Packages/Envelope_3/include/CGAL/Envelope_divide_and_conquer_3.h,v $
// $Id$ // $Revision$ $Date$
// // $Name: $
// //
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il> // Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
@ -23,13 +23,13 @@
#define CGAL_ENVELOPE_SAVE_COMPARISONS #define CGAL_ENVELOPE_SAVE_COMPARISONS
#define CGAL_ENVELOPE_USE_BFS_FACE_ORDER #define CGAL_ENVELOPE_USE_BFS_FACE_ORDER
#include "CGAL/Envelope_base.h" #include <CGAL/Envelope_base.h>
#include <CGAL/Object.h> #include <CGAL/Object.h>
#include <CGAL/enum.h> #include <CGAL/enum.h>
#include <CGAL/Arr_observer.h> #include <CGAL/Arr_observer.h>
#include <CGAL/Overlay_2.h> #include <CGAL/Overlay_2.h>
#include "CGAL/Envelope_element_visitor_3.h" #include <CGAL/Envelope_element_visitor_3.h>
#include "CGAL/No_vertical_decomposition_2.h" #include <CGAL/No_vertical_decomposition_2.h>
#include <CGAL/Timer.h> #include <CGAL/Timer.h>
#include <CGAL/set_dividors.h> #include <CGAL/set_dividors.h>
@ -56,11 +56,11 @@
// of all surfaces // of all surfaces
// - foreach edge, do the same, using the Resolver class. an edge can split to // - foreach edge, do the same, using the Resolver class. an edge can split to
// a constant number of parts, each with its own envelope data. // a constant number of parts, each with its own envelope data.
// - do a decomposition (vertical / partial or other) to make faces with no // - possibly do a decomposition (vertical / partial or other) to make faces
// holes // with no holes
// - foreach face, do the same as for edges, using the Resolver class. // - foreach face, do the same as for edges, using the Resolver class.
// a face can split to a constant number of sub-faces, each with its own // a face can split to a number of sub-faces that are linear with the face's
// envelope data. // size, each with its own envelope data.
// - remove edges between faces with the same envelope data, which do not // - remove edges between faces with the same envelope data, which do not
// contribute to the shape of the envelope (i.e. have the same envelope data // contribute to the shape of the envelope (i.e. have the same envelope data
// as their adjacent faces) // as their adjacent faces)
@ -70,77 +70,39 @@
// b. isolated vertices which have the same envelope data as their incident // b. isolated vertices which have the same envelope data as their incident
// face // face
// Algorithm complexity:
// T(n) = 2*T(n/2) + M(n), M(n) is the complexity of the merge step
// T(1) = O(1) since we assume the projected boundary is composed of constant
// number of curves, and we get a const diagram.
// M(n) = overlay + resolve + remove
// overlay: O(n^(2+e))
// remove: the pass is linear in diagram size (after overlay & resolve),
// i.e. O(n^(2+e)), but the check of equality can be linear with the
// ammount of surfaces (?)
// resolve: vertex is constant
// edge: is constant since we have only const number of intersections
// between surfaces and curves
// face: copy step - linear in face size
// zone step - sub linear in the face's size? (do the holes destroy?)
// compare step - we have const number of sub-faces, and we conclude
// for boundary so we get linear comlexity (by size of
// face)
// TODO: maybe it is better not do a decomposition at all, but the Resolver
// will support holes inside the face?
// does it spoil the complexity of the algorithm?
// should be careful with holes inside holes inside holes etc.
// the algorithm deals with some degenerate input including: // the algorithm deals with some degenerate input including:
// 1. more than one surface on faces, edges, vertices // 1. more than one surface on faces, edges, vertices
// (the minimization diagram should also support this) // (the minimization diagram should also support this)
// 2. all degenerate cases in 2d (the minimization diagram model is // 2. all degenerate cases in 2d (the minimization diagram model is
// responsible for) // responsible for)
// the algorithm doesn't deal with:
// 1. vertical edges in the envelope (the naive vertical decomposition doesn't
// support this)
// some degenerate cases in the responsibility of the geometric traits // some degenerate cases in the responsibility of the geometric traits
// 1. overlapping surfaces // 1. overlapping surfaces
// 2. a vertical surface that contributes only edge (or edges) to the envelope // 2. a vertical surface that contributes only edge (or edges) to the envelope
//#define CGAL_DEBUG_ENVELOPE_DEQ_3 //#define CGAL_DEBUG_ENVELOPE_DEQ_3
//#define CGAL_BENCH_ENVELOPE_DAC //#define CGAL_BENCH_ENVELOPE_DAC
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
// The algorithm has 4 template parameters: // The algorithm has 5 template parameters:
// 1. EnvelopeTraits_3 - the geometric traits class // 1. EnvelopeTraits_3 - the geometric traits class
// 2. MinimizationDiagram_2 - the type of the output, which is a planar map // 2. MinimizationDiagram_2 - the type of the output, which is an arrangement
// with additional information (list of surfaces) // with additional information (list of surfaces)
// in vertices, edges & faces // in vertices, edges & faces
// 3. VerticalDecomposition_2 - a vertical decomposition for 2D // 3. VerticalDecomposition_2 - a vertical decomposition for 2D
// MinimizationDiagram_2 so that we can switch // MinimizationDiagram_2 so that we can switch
// from partial/full/other/none decomposition. // from partial/full/other/none decomposition.
// 4. EnvelopeResolver_3 - part of the algorithm that solves the shape of // 4. EnvelopeResolver_3 - part of the algorithm that solves the shape of
// the envelope between 2 surfaces over an edge or // the envelope between 2 surfaces over a feature
// a face we might use the default Envelope_general_resolver // of the arrangement
// (which works for general surfaces) // 5. Overlay_2 - overlay of 2 MinimizationDiagram_2
// or create specific resolver for specific geometry if it can be
// more efficient
// 5. Overlay_2 - overlay 2 MinimizationDiagram_2 (to be removed)
template <class EnvelopeTraits_3, class MinimizationDiagram_2, template <class EnvelopeTraits_3, class MinimizationDiagram_2,
class VerticalDecomposition_2 = No_vertical_decomposition_2<MinimizationDiagram_2>, class VerticalDecomposition_2 = No_vertical_decomposition_2<MinimizationDiagram_2>,
class EnvelopeResolver_3 = class EnvelopeResolver_3 =
Envelope_element_visitor_3<EnvelopeTraits_3, MinimizationDiagram_2>, Envelope_element_visitor_3<EnvelopeTraits_3, MinimizationDiagram_2>,
class Overlay_2 = Envelope_overlay_2<MinimizationDiagram_2> > class Overlay_2 = Envelope_overlay_2<MinimizationDiagram_2> >
class Envelope_divide_and_conquer_3 : public Envelope_base_3<EnvelopeTraits_3> class Envelope_divide_and_conquer_3
{ {
public: public:
typedef EnvelopeTraits_3 Traits; typedef EnvelopeTraits_3 Traits;
@ -158,7 +120,6 @@ public:
typedef Envelope_divide_and_conquer_3<Traits, Minimization_diagram_2, typedef Envelope_divide_and_conquer_3<Traits, Minimization_diagram_2,
Vertical_decomposition_2, Vertical_decomposition_2,
EnvelopeResolver_3, EnvelopeResolver_3,
Overlay_2> Self; Overlay_2> Self;
@ -188,7 +149,6 @@ public:
Envelope_divide_and_conquer_3() Envelope_divide_and_conquer_3()
{ {
// Allocate the traits. // Allocate the traits.
traits = new Traits; traits = new Traits;
own_traits = true; own_traits = true;
@ -210,7 +170,6 @@ public:
virtual ~Envelope_divide_and_conquer_3() virtual ~Envelope_divide_and_conquer_3()
{ {
// Free the traits object, if necessary. // Free the traits object, if necessary.
if (own_traits) if (own_traits)
delete traits; delete traits;
@ -227,6 +186,7 @@ public:
construct_lu_envelope(begin, end, result, dividor); construct_lu_envelope(begin, end, result, dividor);
} }
// compute the envelope of surfaces in 3D using the given set dividor // compute the envelope of surfaces in 3D using the given set dividor
template <class SurfaceIterator, class SetDividor> template <class SurfaceIterator, class SetDividor>
void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end, void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end,
@ -245,6 +205,7 @@ public:
init_stats(); init_stats();
envelope_timer.start(); envelope_timer.start();
// make the general surfaces xy-monotone // make the general surfaces xy-monotone
std::list<Xy_monotone_surface_3> xy_monotones; std::list<Xy_monotone_surface_3> xy_monotones;
for(; begin != end; ++begin) for(; begin != end; ++begin)
@ -279,8 +240,6 @@ public:
void reset() void reset()
{ {
// reset caches
resolver->reset(); resolver->reset();
// reset statistical measures // reset statistical measures
init_stats(); init_stats();
@ -293,16 +252,15 @@ public:
<< '\t'; << '\t';
if (decompose_timer.time() > 0) if (decompose_timer.time() > 0)
std::cout << decompose_timer.time() << '\t'; std::cout << decompose_timer.time() << '\t';
resolver->print_bench();
} }
void print_bench_header() const void print_bench_header() const
{ {
std::cout << "extra features" std::cout << "extra features"
<< '\t'; << '\t';
if (decompose_timer.time() > 0) if (decompose_timer.time() > 0)
std::cout << "decomposition time" << '\t'; std::cout << "decomposition time" << '\t';
resolver->print_bench_header();
} }
protected: protected:
@ -320,6 +278,7 @@ protected:
} }
SurfaceIterator first = begin++; SurfaceIterator first = begin++;
if (begin == end) if (begin == end)
{ {
// only one surface is in the collection. insert it the result // only one surface is in the collection. insert it the result
@ -355,7 +314,6 @@ protected:
sum_num_edges += result.number_of_edges(); sum_num_edges += result.number_of_edges();
sum_num_faces += result.number_of_faces(); sum_num_faces += result.number_of_faces();
resolver->reset_cache();
result1.clear(); result1.clear();
result2.clear(); result2.clear();
@ -382,7 +340,6 @@ protected:
// todo: should we do incremental/aggregate insert? // todo: should we do incremental/aggregate insert?
// insert(result, boundary_curves.begin(), boundary_curves.end()); // insert(result, boundary_curves.begin(), boundary_curves.end());
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "inserted one surface to result" << std::endl; std::cout << "inserted one surface to result" << std::endl;
std::cout << "number of faces in result: " << result.number_of_faces() << std::endl; std::cout << "number of faces in result: " << result.number_of_faces() << std::endl;
@ -402,6 +359,7 @@ protected:
// unbounded face has no data // unbounded face has no data
ccb_he->set_is_equal_data_in_face(false); ccb_he->set_is_equal_data_in_face(false);
ccb_he->set_has_equal_data_in_face(false); ccb_he->set_has_equal_data_in_face(false);
ccb_he->set_has_equal_data_in_target_and_face(false);
Face_handle face = ccb_he->twin()->face(); Face_handle face = ccb_he->twin()->face();
if (face->is_unbounded()) if (face->is_unbounded())
@ -409,11 +367,13 @@ protected:
face->set_data(surf); face->set_data(surf);
// update the is/has equal_data_in_face in all the halfedges of the face's // update the is/has equal_data_in_face in all the halfedges of the face's
// boundary to true // boundary to true
// and also target-face has_equal flag to true
Ccb_halfedge_circulator face_hec = face->outer_ccb(); Ccb_halfedge_circulator face_hec = face->outer_ccb();
Ccb_halfedge_circulator face_hec_begin = face_hec; Ccb_halfedge_circulator face_hec_begin = face_hec;
do { do {
face_hec->set_is_equal_data_in_face(true); face_hec->set_is_equal_data_in_face(true);
face_hec->set_has_equal_data_in_face(true); face_hec->set_has_equal_data_in_face(true);
face_hec->set_has_equal_data_in_target_and_face(true);
++face_hec; ++face_hec;
} while(face_hec != face_hec_begin); } while(face_hec != face_hec_begin);
@ -425,10 +385,10 @@ protected:
do { do {
face_hec->set_is_equal_data_in_face(true); face_hec->set_is_equal_data_in_face(true);
face_hec->set_has_equal_data_in_face(true); face_hec->set_has_equal_data_in_face(true);
face_hec->set_has_equal_data_in_target_and_face(true);
++face_hec; ++face_hec;
} while(face_hec != face_hec_begin); } while(face_hec != face_hec_begin);
} }
} }
// update other faces to indicate that no surface is over them // update other faces to indicate that no surface is over them
@ -449,6 +409,7 @@ protected:
do { do {
face_hec->set_is_equal_data_in_face(false); face_hec->set_is_equal_data_in_face(false);
face_hec->set_has_equal_data_in_face(false); face_hec->set_has_equal_data_in_face(false);
face_hec->set_has_equal_data_in_target_and_face(false);
++face_hec; ++face_hec;
} while(face_hec != face_hec_begin); } while(face_hec != face_hec_begin);
} }
@ -459,6 +420,7 @@ protected:
do { do {
face_hec->set_is_equal_data_in_face(false); face_hec->set_is_equal_data_in_face(false);
face_hec->set_has_equal_data_in_face(false); face_hec->set_has_equal_data_in_face(false);
face_hec->set_has_equal_data_in_target_and_face(false);
++face_hec; ++face_hec;
} while(face_hec != face_hec_begin); } while(face_hec != face_hec_begin);
} }
@ -466,10 +428,6 @@ protected:
} }
uface->set_no_data(); uface->set_no_data();
// #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
// std::cout << "after updating face data" << std::endl;
// #endif
// update information in all the edges & vertices to indicate that // update information in all the edges & vertices to indicate that
// this surface is the envelope // this surface is the envelope
Halfedge_iterator hi = result.halfedges_begin(); Halfedge_iterator hi = result.halfedges_begin();
@ -500,14 +458,12 @@ protected:
CGAL_assertion(verify_flags(result)); CGAL_assertion(verify_flags(result));
// some statistics // some statistics
sum_num_vertices += result.number_of_vertices(); sum_num_vertices += result.number_of_vertices();
sum_num_edges += result.number_of_edges(); sum_num_edges += result.number_of_edges();
sum_num_faces += result.number_of_faces(); sum_num_faces += result.number_of_faces();
one_surface_timer.stop(); one_surface_timer.stop();
} }
public: public:
@ -526,8 +482,6 @@ public:
CGAL_assertion_msg(is_valid(result), "after overlay result is not valid"); CGAL_assertion_msg(is_valid(result), "after overlay result is not valid");
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "after overlay, print faces: " << std::endl; std::cout << "after overlay, print faces: " << std::endl;
overlay.print_faces(result); overlay.print_faces(result);
@ -537,7 +491,6 @@ public:
<< result.number_of_edges() << std::endl; << result.number_of_edges() << std::endl;
std::cout << "after overlay, number of faces: " std::cout << "after overlay, number of faces: "
<< result.number_of_faces() << std::endl; << result.number_of_faces() << std::endl;
#endif #endif
// make sure the aux flags are correctly set by the overlay // make sure the aux flags are correctly set by the overlay
@ -547,12 +500,10 @@ public:
// which surfaces are on the envelope // which surfaces are on the envelope
// a face can be cut, or faces can be merged. // a face can be cut, or faces can be merged.
// now the minimization diagram might change - we need to keep data in the // now the minimization diagram might change - we need to keep data in the
// edges, when they're split // edges, when they're split
Keep_edge_data_observer edge_observer(result, this); Keep_edge_data_observer edge_observer(result, this);
// compute the surface on the envelope for each edge // compute the surface on the envelope for each edge
// edge can be split as surfaces can intersect (or touch) over it // edge can be split as surfaces can intersect (or touch) over it
std::list<Halfedge_handle> edges_to_resolve; std::list<Halfedge_handle> edges_to_resolve;
@ -618,7 +569,6 @@ public:
std::list<Face_handle> faces_to_split; std::list<Face_handle> faces_to_split;
#ifdef CGAL_ENVELOPE_USE_BFS_FACE_ORDER #ifdef CGAL_ENVELOPE_USE_BFS_FACE_ORDER
// we traverse the faces of result in BFS order to maximize the // we traverse the faces of result in BFS order to maximize the
// efficiency gain by the conclusion mechanism of // efficiency gain by the conclusion mechanism of
// compare_distance_to_envelope results // compare_distance_to_envelope results
@ -638,10 +588,7 @@ public:
boost::vertex_index_map(index_map). boost::vertex_index_map(index_map).
visitor (bfs_visitor)); visitor (bfs_visitor));
index_map.detach(); index_map.detach();
#else #else
// traverse the faces in arbitrary order // traverse the faces in arbitrary order
Face_iterator fi = result.faces_begin(); Face_iterator fi = result.faces_begin();
for (; fi != result.faces_end(); ++fi) for (; fi != result.faces_end(); ++fi)
@ -657,6 +604,7 @@ public:
{ {
fh->set_decision(EQUAL); fh->set_decision(EQUAL);
fh->set_no_data(); fh->set_no_data();
continue; continue;
} }
else if (!aux_has_no_data(fh, 0) && aux_has_no_data(fh, 1)) else if (!aux_has_no_data(fh, 0) && aux_has_no_data(fh, 1))
@ -701,7 +649,6 @@ public:
vh->set_decision(SECOND); vh->set_decision(SECOND);
continue; continue;
} }
else if (!aux_has_no_data(vh, 0) && aux_has_no_data(vh, 1)) else if (!aux_has_no_data(vh, 0) && aux_has_no_data(vh, 1))
{ {
vh->set_decision(FIRST); vh->set_decision(FIRST);
@ -726,13 +673,11 @@ public:
// make sure the aux flags are correctly after all resolvings // make sure the aux flags are correctly after all resolvings
CGAL_assertion(verify_aux_flags(result)); CGAL_assertion(verify_aux_flags(result));
remove_unneccessary_elements_timer.start(); remove_unneccessary_elements_timer.start();
// finally, remove unneccessary edges, between faces with the same surface // finally, remove unneccessary edges, between faces with the same surface
// (and which are not degenerate) // (and which are not degenerate)
remove_unneccessary_edges(result); remove_unneccessary_edges(result);
CGAL_assertion_msg(result.is_valid(), CGAL_assertion_msg(result.is_valid(),
"after remove edges result is not valid"); "after remove edges result is not valid");
// also remove unneccessary vertices (that were created in the process of // also remove unneccessary vertices (that were created in the process of
@ -754,10 +699,10 @@ public:
// make sure that all the flags are correctly set on the envelope result // make sure that all the flags are correctly set on the envelope result
CGAL_assertion(verify_flags(result)); CGAL_assertion(verify_flags(result));
CGAL_assertion_msg(is_valid(result), "after merge result is not valid"); CGAL_assertion_msg(is_valid(result), "after merge result is not valid");
} }
protected: protected:
// do a vertical decomposition // do a vertical decomposition
@ -795,32 +740,18 @@ protected:
} }
template <class InputIterator> template <class InputIterator>
bool is_equal_data(const InputIterator & begin1, bool is_equal_data(const InputIterator & begin1,
const InputIterator & end1, const InputIterator & end1,
const InputIterator & begin2, const InputIterator & begin2,
const InputIterator & end2) const InputIterator & end2)
{ {
// #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
// std::cout << "in is_equal_data: " << std::endl;
// std::cout << "first group: ";
// InputIterator it = begin1;
// for(; it != end1; ++it)
// std::cout << *it << " , ";
// it = begin2;
// std::cout << "second group: ";
// for(; it != end2; ++it)
// std::cout << *it << " , ";
// std::cout << std::endl;
// #endif
// insert the input data objects into a set // insert the input data objects into a set
std::set<Xy_monotone_surface_3> first(begin1, end1); std::set<Xy_monotone_surface_3> first(begin1, end1);
std::set<Xy_monotone_surface_3> second(begin2, end2); std::set<Xy_monotone_surface_3> second(begin2, end2);
if (first.size() != second.size()) if (first.size() != second.size())
return false; return false;
return (first == second); return (first == second);
} }
@ -888,6 +819,7 @@ protected:
{ {
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "remove_edge" << (*ci)->curve() << std::endl; std::cout << "remove_edge" << (*ci)->curve() << std::endl;
#endif #endif
// if the endpoints become isolated after the removal we need to remove // if the endpoints become isolated after the removal we need to remove
// them if they have the same data as the edge // them if they have the same data as the edge
@ -904,6 +836,11 @@ protected:
h->get_is_equal_aux_data_in_target(0)); h->get_is_equal_aux_data_in_target(0));
bool trg_is_equal_1 = (h->get_is_equal_aux_data_in_face(1) && bool trg_is_equal_1 = (h->get_is_equal_aux_data_in_face(1) &&
h->get_is_equal_aux_data_in_target(1)); h->get_is_equal_aux_data_in_target(1));
bool src_has_equal_0 = h->twin()->get_has_equal_aux_data_in_target_and_face(0);
bool src_has_equal_1 = h->twin()->get_has_equal_aux_data_in_target_and_face(1);
bool trg_has_equal_0 = h->get_has_equal_aux_data_in_target_and_face(0);
bool trg_has_equal_1 = h->get_has_equal_aux_data_in_target_and_face(1);
result.remove_edge(*ci, remove_src, remove_trg); result.remove_edge(*ci, remove_src, remove_trg);
// otherwise, we should make sure, they will not be removed // otherwise, we should make sure, they will not be removed
// the first check is needed since if the vertex was removed, then the // the first check is needed since if the vertex was removed, then the
@ -917,11 +854,13 @@ protected:
// to be precise we copy from the halfedge-face and halfedge-target relations // to be precise we copy from the halfedge-face and halfedge-target relations
src->set_is_equal_aux_data_in_face(0, src_is_equal_0); src->set_is_equal_aux_data_in_face(0, src_is_equal_0);
src->set_is_equal_aux_data_in_face(1, src_is_equal_1); src->set_is_equal_aux_data_in_face(1, src_is_equal_1);
// todo: the has_equal flags should be updated also - how can we do it? // todo: the has_equal flags should be updated also
// todo: this is temporary:
// make sure h_face is also src face // make sure h_face is also src face
src->set_has_equal_aux_data_in_face(0, has_equal_aux_data(0, src, h_face)); CGAL_assertion(h_face == src->face());
src->set_has_equal_aux_data_in_face(1, has_equal_aux_data(1, src, h_face)); // CGAL_assertion(src_has_equal_0 == has_equal_aux_data(0, src, h_face));
// CGAL_assertion(src_has_equal_1 == has_equal_aux_data(1, src, h_face));
src->set_has_equal_aux_data_in_face(0, src_has_equal_0);
src->set_has_equal_aux_data_in_face(1, src_has_equal_1);
} }
if (!remove_trg && trg->is_isolated()) if (!remove_trg && trg->is_isolated())
{ {
@ -931,10 +870,16 @@ protected:
#endif #endif
trg->set_is_equal_aux_data_in_face(0, trg_is_equal_0); trg->set_is_equal_aux_data_in_face(0, trg_is_equal_0);
trg->set_is_equal_aux_data_in_face(1, trg_is_equal_1); trg->set_is_equal_aux_data_in_face(1, trg_is_equal_1);
// todo: this is temporary:
// make sure h_face is also trg face // make sure h_face is also trg face
trg->set_has_equal_aux_data_in_face(0, has_equal_aux_data(0, trg, h_face)); #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
trg->set_has_equal_aux_data_in_face(1, has_equal_aux_data(1, trg, h_face)); std::cout << "real value for map 1: " << has_equal_aux_data(1, trg, h_face)
<< "flag value: " << trg_has_equal_1 << std::endl;
#endif
CGAL_assertion(h_face == trg->face());
// CGAL_assertion(trg_has_equal_0 == has_equal_aux_data(0, trg, h_face));
// CGAL_assertion(trg_has_equal_1 == has_equal_aux_data(1, trg, h_face));
trg->set_has_equal_aux_data_in_face(0, trg_has_equal_0);
trg->set_has_equal_aux_data_in_face(1, trg_has_equal_1);
} }
} }
@ -961,6 +906,7 @@ protected:
// aux source of a face must be a face! // aux source of a face must be a face!
// aux source of a halfedge can be face or halfedge // aux source of a halfedge can be face or halfedge
// aux source of a vertex can be face, halfedge or vertex // aux source of a vertex can be face, halfedge or vertex
// this is why we start with a check for a face, then halfedge // this is why we start with a check for a face, then halfedge
// and last vertex // and last vertex
@ -1043,6 +989,7 @@ protected:
bool b4 = is_equal_data(begin1, end1, begin2, end2); bool b4 = is_equal_data(begin1, end1, begin2, end2);
); );
// after removes, the aux_source might be wrong for source that // after removes, the aux_source might be wrong for source that
// has no connection to the decision, so cannot use assertions here // has no connection to the decision, so cannot use assertions here
// todo (after return) - is it correct to put it in comment // todo (after return) - is it correct to put it in comment
// CGAL_assertion(equal_first == (b1 && b2)); // CGAL_assertion(equal_first == (b1 && b2));
@ -1114,7 +1061,7 @@ protected:
bool b2 = is_equal_data(begin1, end1, begin2, end2); bool b2 = is_equal_data(begin1, end1, begin2, end2);
); );
// we don't assert here becausethe flags may only be true for // we don't assert here because the flags may only be true for
// aux data that is related to the decision. // aux data that is related to the decision.
//CGAL_assertion(equal_first == b1); //CGAL_assertion(equal_first == b1);
//CGAL_assertion(equal_second == b2); //CGAL_assertion(equal_second == b2);
@ -1134,7 +1081,6 @@ protected:
CGAL_assertion(equal_first == b1); CGAL_assertion(equal_first == b1);
CGAL_assertion(equal_second == b2); CGAL_assertion(equal_second == b2);
return (equal_first && equal_second); return (equal_first && equal_second);
} }
} }
@ -1152,10 +1098,10 @@ protected:
// now, check the equality of the surfaces list according to the decision // now, check the equality of the surfaces list according to the decision
CGAL::Dac_decision decision = vh->get_decision(); CGAL::Dac_decision decision = vh->get_decision();
bool equal_first = (vh->get_is_equal_aux_data_in_face(0)); bool equal_first = (vh->get_is_equal_aux_data_in_face(0));
bool equal_second = (vh->get_is_equal_aux_data_in_face(1)); bool equal_second = (vh->get_is_equal_aux_data_in_face(1));
// we assert that the flags' values are correct using comparison of data // we assert that the flags' values are correct using comparison of data
// as in the old way (using set operations) // as in the old way (using set operations)
CGAL_assertion_code ( CGAL_assertion_code (
@ -1204,7 +1150,6 @@ protected:
CGAL_assertion(he1 != he2); CGAL_assertion(he1 != he2);
CGAL_assertion(he1->is_decision_set() && he2->is_decision_set()); CGAL_assertion(he1->is_decision_set() && he2->is_decision_set());
if (vh->get_is_fake()) if (vh->get_is_fake())
{ {
CGAL_assertion(he1->get_decision() == he2->get_decision()); CGAL_assertion(he1->get_decision() == he2->get_decision());
@ -1216,8 +1161,6 @@ protected:
// the envelope differs too. // the envelope differs too.
CGAL_assertion(vh == he1->target() && vh == he2->target()); CGAL_assertion(vh == he1->target() && vh == he2->target());
if (vh->get_decision() != he1->get_decision() || if (vh->get_decision() != he1->get_decision() ||
vh->get_decision() != he2->get_decision()) vh->get_decision() != he2->get_decision())
return false; return false;
@ -1287,8 +1230,6 @@ protected:
// on vertical edges, created in the decomposition process, // on vertical edges, created in the decomposition process,
// and are not neccessary // and are not neccessary
// also those vertices with degree 2, that can merge their 2 edges and // also those vertices with degree 2, that can merge their 2 edges and
// with same data as both these edges, can be removed // with same data as both these edges, can be removed
@ -1316,7 +1257,6 @@ protected:
<< " isolated vertices to remove" << std::endl; << " isolated vertices to remove" << std::endl;
#endif #endif
typename Traits::Merge_2 curves_merge = traits->merge_2_object(); typename Traits::Merge_2 curves_merge = traits->merge_2_object();
typename Traits::Are_mergeable_2 curves_can_merge = typename Traits::Are_mergeable_2 curves_can_merge =
traits->are_mergeable_2_object(); traits->are_mergeable_2_object();
@ -1344,6 +1284,7 @@ protected:
Halfedge_around_vertex_circulator hec2 = hec1++; Halfedge_around_vertex_circulator hec2 = hec1++;
Halfedge_handle he1 = hec1, he2 = hec2; Halfedge_handle he1 = hec1, he2 = hec2;
const X_monotone_curve_2& a = he1->curve(), b = he2->curve(); const X_monotone_curve_2& a = he1->curve(), b = he2->curve();
CGAL_assertion(vh->is_decision_set() || curves_can_merge(a,b)); CGAL_assertion(vh->is_decision_set() || curves_can_merge(a,b));
if (vh->is_decision_set() && !curves_can_merge(a,b)) if (vh->is_decision_set() && !curves_can_merge(a,b))
@ -1376,12 +1317,19 @@ protected:
he1->set_is_equal_aux_data_in_target(1, he2->twin()->get_is_equal_aux_data_in_target(1)); he1->set_is_equal_aux_data_in_target(1, he2->twin()->get_is_equal_aux_data_in_target(1));
he1->set_has_equal_aux_data_in_target(0, he2->twin()->get_has_equal_aux_data_in_target(0)); he1->set_has_equal_aux_data_in_target(0, he2->twin()->get_has_equal_aux_data_in_target(0));
he1->set_has_equal_aux_data_in_target(1, he2->twin()->get_has_equal_aux_data_in_target(1)); he1->set_has_equal_aux_data_in_target(1, he2->twin()->get_has_equal_aux_data_in_target(1));
he1->set_has_equal_aux_data_in_target_and_face
(0, he2->twin()->get_has_equal_aux_data_in_target_and_face(0));
he1->set_has_equal_aux_data_in_target_and_face
(1, he2->twin()->get_has_equal_aux_data_in_target_and_face(1));
he2->set_is_equal_aux_data_in_target(0, he1->twin()->get_is_equal_aux_data_in_target(0)); he2->set_is_equal_aux_data_in_target(0, he1->twin()->get_is_equal_aux_data_in_target(0));
he2->set_is_equal_aux_data_in_target(1, he1->twin()->get_is_equal_aux_data_in_target(1)); he2->set_is_equal_aux_data_in_target(1, he1->twin()->get_is_equal_aux_data_in_target(1));
he2->set_has_equal_aux_data_in_target(0, he1->twin()->get_has_equal_aux_data_in_target(0)); he2->set_has_equal_aux_data_in_target(0, he1->twin()->get_has_equal_aux_data_in_target(0));
he2->set_has_equal_aux_data_in_target(1, he1->twin()->get_has_equal_aux_data_in_target(1)); he2->set_has_equal_aux_data_in_target(1, he1->twin()->get_has_equal_aux_data_in_target(1));
he2->set_has_equal_aux_data_in_target_and_face
(0, he1->twin()->get_has_equal_aux_data_in_target_and_face(0));
he2->set_has_equal_aux_data_in_target_and_face
(1, he1->twin()->get_has_equal_aux_data_in_target_and_face(1));
// order of halfedges for merge doesn't matter // order of halfedges for merge doesn't matter
Halfedge_handle new_edge = result.merge_edge(he1, he2 ,c); Halfedge_handle new_edge = result.merge_edge(he1, he2 ,c);
@ -1468,8 +1416,6 @@ protected:
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << hi->curve() << std::endl; std::cout << hi->curve() << std::endl;
#endif #endif
update_envelope_surfaces_by_decision(hi); update_envelope_surfaces_by_decision(hi);
} }
@ -1514,6 +1460,7 @@ protected:
{ {
is_equal &= (is_equal_first & is_equal_second); is_equal &= (is_equal_first & is_equal_second);
// we check if the halfedge has a different decision, and if so, // we check if the halfedge has a different decision, and if so,
// we update the flag according to the halfedge decision // we update the flag according to the halfedge decision
decision = h->get_decision(); decision = h->get_decision();
if (decision == FIRST) if (decision == FIRST)
@ -1530,6 +1477,7 @@ protected:
void update_edge_target_flags(Halfedge_handle h) void update_edge_target_flags(Halfedge_handle h)
{ {
bool is_equal, has_equal; bool is_equal, has_equal;
is_equal = (h->get_decision() == h->target()->get_decision()); is_equal = (h->get_decision() == h->target()->get_decision());
// has equal can be true even if the decision is not the same, // has equal can be true even if the decision is not the same,
// but has same surfaces, i.e. one of the features got BOTH // but has same surfaces, i.e. one of the features got BOTH
@ -1571,6 +1519,38 @@ protected:
h->set_is_equal_data_in_target(is_equal); h->set_is_equal_data_in_target(is_equal);
h->set_has_equal_data_in_target(has_equal); h->set_has_equal_data_in_target(has_equal);
} }
void update_target_face_flags(Halfedge_handle h)
{
bool has_equal;
// has equal can be true even if the decision is not the same,
// but has same surfaces, i.e. one of the features got BOTH
// decision, and the other didn't
has_equal = (h->face()->get_decision() == h->target()->get_decision() ||
h->face()->get_decision() == BOTH ||
h->target()->get_decision() == BOTH);
CGAL::Dac_decision decision = h->face()->get_decision();
bool has_equal_first = (h->get_has_equal_aux_data_in_target_and_face(0));
bool has_equal_second = (h->get_has_equal_aux_data_in_target_and_face(1));
if (decision == FIRST)
has_equal &= has_equal_first;
else if (decision == SECOND)
has_equal &= has_equal_second;
else
{
// we check if the vertex has a different decision, and if so,
// we update the flag according to the vertex decision
decision = h->target()->get_decision();
if (decision == FIRST)
has_equal &= has_equal_first;
else if (decision == SECOND)
has_equal &= has_equal_second;
else
has_equal &= (has_equal_first & has_equal_second);
}
h->set_has_equal_data_in_target_and_face(has_equal);
}
void update_vertex_face_flags(Vertex_handle v, Face_handle f) void update_vertex_face_flags(Vertex_handle v, Face_handle f)
{ {
@ -1626,9 +1606,9 @@ protected:
Halfedge_iterator hi = result.halfedges_begin(); Halfedge_iterator hi = result.halfedges_begin();
for(; hi != result.halfedges_end(); ++hi) for(; hi != result.halfedges_end(); ++hi)
{ {
update_edge_face_flags(hi); update_edge_face_flags(hi);
update_edge_target_flags(hi); update_edge_target_flags(hi);
update_target_face_flags(hi);
} }
// vertices // vertices
@ -1757,6 +1737,7 @@ public:
<< " seconds" << std::endl; << " seconds" << std::endl;
std::cout << std::endl; std::cout << std::endl;
resolver->print_times(); resolver->print_times();
// std::cout << std::endl; // std::cout << std::endl;
@ -1774,6 +1755,7 @@ public:
std::cout << "the number of extra features: " std::cout << "the number of extra features: "
<< (sum_num_vertices+sum_num_faces+sum_num_edges)- << (sum_num_vertices+sum_num_faces+sum_num_edges)-
(result_num_vertices+result_num_edges+result_num_faces) (result_num_vertices+result_num_edges+result_num_faces)
<< std::endl; << std::endl;
std::cout << std::endl; std::cout << std::endl;
traits->print_times(); traits->print_times();
@ -1826,14 +1808,12 @@ protected:
if (assign(v, o)) if (assign(v, o))
return v->is_equal_data(begin, end); return v->is_equal_data(begin, end);
else if (assign(h, o)) else if (assign(h, o))
return h->is_equal_data(begin, end); return h->is_equal_data(begin, end);
else else
{ {
CGAL_assertion(assign(f, o)); CGAL_assertion(assign(f, o));
assign(f, o); assign(f, o);
return f->is_equal_data(begin, end); return f->is_equal_data(begin, end);
} }
} }
bool has_equal_data(Object o, bool has_equal_data(Object o,
@ -1848,7 +1828,6 @@ protected:
if (assign(v, o)) if (assign(v, o))
return v->has_equal_data(begin, end); return v->has_equal_data(begin, end);
else if (assign(h, o)) else if (assign(h, o))
return h->has_equal_data(begin, end); return h->has_equal_data(begin, end);
else else
{ {
@ -1877,6 +1856,7 @@ protected:
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "halfedge: " << face_hec->source()->point() std::cout << "halfedge: " << face_hec->source()->point()
<< " --> " << face_hec->target()->point() << " decision: " << " --> " << face_hec->target()->point() << " decision: "
<< face_hec->get_decision() << std::endl; << face_hec->get_decision() << std::endl;
std::cout << "vertex: " << face_hec->target()->point() std::cout << "vertex: " << face_hec->target()->point()
<< " decision: " << face_hec->target()->get_decision() << " decision: " << face_hec->target()->get_decision()
@ -1891,7 +1871,6 @@ protected:
{ {
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "inner ccb: " << std::endl; std::cout << "inner ccb: " << std::endl;
#endif #endif
face_hec = face_hec_begin = (*inner_iter); face_hec = face_hec_begin = (*inner_iter);
do { do {
@ -1924,13 +1903,13 @@ protected:
continue; continue;
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
// std::cout << "verify_aux_flags on edge " << h->source()->point() std::cout << "verify_aux_flags on edge " << h->source()->point()
// << " --> " << h->target()->point() << std::endl; << " --> " << h->target()->point() << std::endl;
#endif #endif
Object h_src1 = h->get_aux_source(0); Object h_src1 = h->get_aux_source(0);
Object h_src2 = h->get_aux_source(1); Object h_src2 = h->get_aux_source(1);
// check face flags // check halfedge-face flags
Face_handle f = h->face(); Face_handle f = h->face();
Object f_src1 = f->get_aux_source(0); Object f_src1 = f->get_aux_source(0);
Object f_src2 = f->get_aux_source(1); Object f_src2 = f->get_aux_source(1);
@ -1963,12 +1942,13 @@ protected:
h->get_has_equal_aux_data_in_face(1)); h->get_has_equal_aux_data_in_face(1));
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
// check target flags // check halfedge-target flags
Vertex_handle v = h->target(); Vertex_handle v = h->target();
Object v_src1 = v->get_aux_source(0); Object v_src1 = v->get_aux_source(0);
Object v_src2 = v->get_aux_source(1); Object v_src2 = v->get_aux_source(1);
get_data_iterators(h_src1, begin, end); get_data_iterators(h_src1, begin, end);
all_ok = (is_equal_data(v_src1, begin, end) == all_ok = (is_equal_data(v_src1, begin, end) ==
h->get_is_equal_aux_data_in_target(0)); h->get_is_equal_aux_data_in_target(0));
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
@ -1985,6 +1965,17 @@ protected:
all_ok = (has_equal_data(v_src2, begin, end) == all_ok = (has_equal_data(v_src2, begin, end) ==
h->get_has_equal_aux_data_in_target(1)); h->get_has_equal_aux_data_in_target(1));
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
// check target-face flags
get_data_iterators(v_src1, begin, end);
all_ok = (has_equal_data(f_src1, begin, end) ==
h->get_has_equal_aux_data_in_target_and_face(0));
CGAL_assertion(all_ok);
get_data_iterators(v_src2, begin, end);
all_ok = (has_equal_data(f_src2, begin, end) ==
h->get_has_equal_aux_data_in_target_and_face(1));
CGAL_assertion(all_ok);
} }
Vertex_iterator vi = result.vertices_begin(); Vertex_iterator vi = result.vertices_begin();
@ -2014,7 +2005,6 @@ protected:
<< is_equal_data(f_src1, begin, end) << std::endl; << is_equal_data(f_src1, begin, end) << std::endl;
std::cout << "flags is equal = " std::cout << "flags is equal = "
<< v->get_has_equal_aux_data_in_face(0) << std::endl; << v->get_has_equal_aux_data_in_face(0) << std::endl;
} }
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
@ -2030,7 +2020,6 @@ protected:
all_ok = (has_equal_data(f_src2, begin, end) == all_ok = (has_equal_data(f_src2, begin, end) ==
v->get_has_equal_aux_data_in_face(1)); v->get_has_equal_aux_data_in_face(1));
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
} }
return all_ok; return all_ok;
@ -2058,6 +2047,7 @@ protected:
all_ok = (h->has_equal_data(f->begin_data(), f->end_data()) == all_ok = (h->has_equal_data(f->begin_data(), f->end_data()) ==
h->get_has_equal_data_in_face()); h->get_has_equal_data_in_face());
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
// check halfedge-target flags // check halfedge-target flags
@ -2065,7 +2055,6 @@ protected:
all_ok = (h->is_equal_data(v->begin_data(), v->end_data()) == all_ok = (h->is_equal_data(v->begin_data(), v->end_data()) ==
h->get_is_equal_data_in_target()); h->get_is_equal_data_in_target());
if (!all_ok) if (!all_ok)
std::cout << "flag value: " << h->get_is_equal_data_in_target() std::cout << "flag value: " << h->get_is_equal_data_in_target()
<< " real value " << h->is_equal_data(v->begin_data(), v->end_data()) << " real value " << h->is_equal_data(v->begin_data(), v->end_data())
@ -2079,6 +2068,16 @@ protected:
<< " real value " << h->has_equal_data(v->begin_data(), v->end_data()) << " real value " << h->has_equal_data(v->begin_data(), v->end_data())
<< std::endl; << std::endl;
CGAL_assertion(all_ok); CGAL_assertion(all_ok);
// check target-face flags
all_ok = (h->face()->has_equal_data(v->begin_data(), v->end_data()) ==
h->get_has_equal_data_in_target_and_face());
if (!all_ok)
std::cout << "flag value: " << h->get_has_equal_data_in_target_and_face()
<< " real value " << h->face()->has_equal_data(v->begin_data(), v->end_data())
<< std::endl;
CGAL_assertion(all_ok);
} }
Vertex_iterator vi = result.vertices_begin(); Vertex_iterator vi = result.vertices_begin();
@ -2131,6 +2130,7 @@ protected:
CGAL_assertion_msg(all_ok, "aux source (1) not set over vertex"); CGAL_assertion_msg(all_ok, "aux source (1) not set over vertex");
all_ok &= (vh->is_decision_set()); all_ok &= (vh->is_decision_set());
CGAL_assertion_msg(all_ok, "decision was not set over vertex"); CGAL_assertion_msg(all_ok, "decision was not set over vertex");
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "decision on vertex: " << vh->get_decision() << std::endl; std::cout << "decision on vertex: " << vh->get_decision() << std::endl;
#endif #endif
@ -2156,6 +2156,7 @@ protected:
for(; fi != result.faces_end(); ++fi) for(; fi != result.faces_end(); ++fi)
{ {
Face_handle fh = fi; Face_handle fh = fi;
all_ok &= (fh->get_aux_is_set(0)); all_ok &= (fh->get_aux_is_set(0));
CGAL_assertion_msg(all_ok, "aux source (0) not set over face"); CGAL_assertion_msg(all_ok, "aux source (0) not set over face");
all_ok &= (fh->get_aux_is_set(1)); all_ok &= (fh->get_aux_is_set(1));
@ -2309,6 +2310,7 @@ protected:
// we need to set halfedge-target is_equal flags // we need to set halfedge-target is_equal flags
// we need the other halfedge that points to the face and to the vertex // we need the other halfedge that points to the face and to the vertex
// if exists (this is the twin's prev halfedge), or the isolated vertex info // if exists (this is the twin's prev halfedge), or the isolated vertex info
// we also set has equal flags
if (e->twin()->prev() != e) if (e->twin()->prev() != e)
{ {
CGAL_assertion(e->twin()->face() == e->twin()->prev()->face()); CGAL_assertion(e->twin()->face() == e->twin()->prev()->face());
@ -2316,26 +2318,57 @@ protected:
e->set_is_equal_aux_data_in_target(0, prev->get_is_equal_aux_data_in_face(0) && e->set_is_equal_aux_data_in_target(0, prev->get_is_equal_aux_data_in_face(0) &&
prev->get_is_equal_aux_data_in_target(0)); prev->get_is_equal_aux_data_in_target(0));
e->set_is_equal_aux_data_in_target(1, prev->get_is_equal_aux_data_in_face(1) && e->set_is_equal_aux_data_in_target(1, prev->get_is_equal_aux_data_in_face(1) &&
prev->get_is_equal_aux_data_in_target(1)); prev->get_is_equal_aux_data_in_target(1));
e->set_has_equal_aux_data_in_target(0,
prev->get_has_equal_aux_data_in_target_and_face(0));
e->set_has_equal_aux_data_in_target(1,
prev->get_has_equal_aux_data_in_target_and_face(1));
e->set_has_equal_aux_data_in_target_and_face(0,
prev->get_has_equal_aux_data_in_target_and_face(0));
e->set_has_equal_aux_data_in_target_and_face(1,
prev->get_has_equal_aux_data_in_target_and_face(1));
} }
else else
{ {
// the target of e was isolated, before we added e // the target of e was isolated, before we added e
e->set_is_equal_aux_data_in_target(0, e->target()->get_is_equal_aux_data_in_face(0)); e->set_is_equal_aux_data_in_target(0,
e->set_is_equal_aux_data_in_target(1, e->target()->get_is_equal_aux_data_in_face(1)); e->target()->get_is_equal_aux_data_in_face(0));
e->set_is_equal_aux_data_in_target(1,
e->target()->get_is_equal_aux_data_in_face(1));
e->set_has_equal_aux_data_in_target(0,
e->target()->get_has_equal_aux_data_in_face(0));
e->set_has_equal_aux_data_in_target(1,
e->target()->get_has_equal_aux_data_in_face(1));
e->set_has_equal_aux_data_in_target_and_face(0,
e->target()->get_has_equal_aux_data_in_face(0));
e->set_has_equal_aux_data_in_target_and_face(1,
e->target()->get_has_equal_aux_data_in_face(1));
} }
if (e->prev() != e->twin()) if (e->prev() != e->twin())
{ {
CGAL_assertion(e->face() == e->prev()->face()); CGAL_assertion(e->face() == e->prev()->face());
Halfedge_handle prev = e->prev(); Halfedge_handle prev = e->prev();
e->twin()->set_is_equal_aux_data_in_target(0, prev->get_is_equal_aux_data_in_face(0) && e->twin()->set_is_equal_aux_data_in_target(0, prev->get_is_equal_aux_data_in_face(0) &&
prev->get_is_equal_aux_data_in_target(0)); prev->get_is_equal_aux_data_in_target(0));
e->twin()->set_is_equal_aux_data_in_target(1, prev->get_is_equal_aux_data_in_face(1) && e->twin()->set_is_equal_aux_data_in_target(1, prev->get_is_equal_aux_data_in_face(1) &&
prev->get_is_equal_aux_data_in_target(1)); prev->get_is_equal_aux_data_in_target(1));
e->twin()->set_has_equal_aux_data_in_target(0,
prev->get_has_equal_aux_data_in_target_and_face(0));
e->twin()->set_has_equal_aux_data_in_target(1,
prev->get_has_equal_aux_data_in_target_and_face(1));
e->twin()->set_has_equal_aux_data_in_target_and_face(0,
prev->get_has_equal_aux_data_in_target_and_face(0));
e->twin()->set_has_equal_aux_data_in_target_and_face(1,
prev->get_has_equal_aux_data_in_target_and_face(1));
} }
else else
{ {
@ -2344,6 +2377,16 @@ protected:
e->source()->get_is_equal_aux_data_in_face(0)); e->source()->get_is_equal_aux_data_in_face(0));
e->twin()->set_is_equal_aux_data_in_target(1, e->twin()->set_is_equal_aux_data_in_target(1,
e->source()->get_is_equal_aux_data_in_face(1)); e->source()->get_is_equal_aux_data_in_face(1));
e->twin()->set_has_equal_aux_data_in_target(0,
e->source()->get_has_equal_aux_data_in_face(0));
e->twin()->set_has_equal_aux_data_in_target(1,
e->source()->get_has_equal_aux_data_in_face(1));
e->twin()->set_has_equal_aux_data_in_target_and_face(0,
e->source()->get_has_equal_aux_data_in_face(0));
e->twin()->set_has_equal_aux_data_in_target_and_face(1,
e->source()->get_has_equal_aux_data_in_face(1));
} }
// we don't set the halfedge-target has_equal flags, because the setting will not // we don't set the halfedge-target has_equal flags, because the setting will not
@ -2352,10 +2395,8 @@ protected:
// TODO: if we set correctly all has_equal falgs, maybe we can get rid // TODO: if we set correctly all has_equal falgs, maybe we can get rid
// of "fake" flags // of "fake" flags
// TODO: if a fake edge overlaps a projected intersection, and thus // TODO: if a fake edge overlaps a projected intersection, and thus
// becomes not fake (and we will not want to remove it at the end) - // becomes not fake (and we will not want to remove it at the end) -
// what happens in the code? check and fix! // what happens in the code? check and fix!
} }
protected: protected:
Self *base; Self *base;
@ -2384,7 +2425,6 @@ protected:
} }
virtual void before_split_edge (Halfedge_handle e, virtual void before_split_edge (Halfedge_handle e,
Vertex_handle v, Vertex_handle v,
const X_monotone_curve_2& c1, const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2) const X_monotone_curve_2& c2)
@ -2426,7 +2466,6 @@ protected:
new_vertex->set_decision(org_he->get_decision()); new_vertex->set_decision(org_he->get_decision());
} }
if (org_he->get_aux_is_set(0)) if (org_he->get_aux_is_set(0))
{ {
new_vertex->set_aux_source(0, org_he->get_aux_source(0)); new_vertex->set_aux_source(0, org_he->get_aux_source(0));
new_he->set_aux_source(0, org_he->get_aux_source(0)); new_he->set_aux_source(0, org_he->get_aux_source(0));
@ -2443,7 +2482,6 @@ protected:
new_he->twin()->set_is_fake(org_he->get_is_fake()); new_he->twin()->set_is_fake(org_he->get_is_fake());
new_vertex->set_is_fake(org_he->get_is_fake()); new_vertex->set_is_fake(org_he->get_is_fake());
// update all new bools // update all new bools
new_he->set_is_equal_aux_data_in_face(0, org_he->get_is_equal_aux_data_in_face(0)); new_he->set_is_equal_aux_data_in_face(0, org_he->get_is_equal_aux_data_in_face(0));
new_he->twin()->set_is_equal_aux_data_in_face(0, org_he->twin()->get_is_equal_aux_data_in_face(0)); new_he->twin()->set_is_equal_aux_data_in_face(0, org_he->twin()->get_is_equal_aux_data_in_face(0));
@ -2464,12 +2502,25 @@ protected:
new_he->set_has_equal_aux_data_in_target(1, org_he->get_has_equal_aux_data_in_target(1)); new_he->set_has_equal_aux_data_in_target(1, org_he->get_has_equal_aux_data_in_target(1));
org_he->set_has_equal_aux_data_in_target(0, !base->aux_has_no_data(org_he, 0)); org_he->set_has_equal_aux_data_in_target(0, !base->aux_has_no_data(org_he, 0));
org_he->set_has_equal_aux_data_in_target(1, !base->aux_has_no_data(org_he, 1)); org_he->set_has_equal_aux_data_in_target(1, !base->aux_has_no_data(org_he, 1));
new_he->set_has_equal_aux_data_in_target_and_face
(0, org_he->get_has_equal_aux_data_in_target_and_face(0));
new_he->set_has_equal_aux_data_in_target_and_face
(1, org_he->get_has_equal_aux_data_in_target_and_face(1));
org_he->set_has_equal_aux_data_in_target_and_face
(0, org_he->get_has_equal_aux_data_in_face(0));
org_he->set_has_equal_aux_data_in_target_and_face
(1, org_he->get_has_equal_aux_data_in_face(1));
// new_he->source is the new vertex, and org_he->source is the original vertex // new_he->source is the new vertex, and org_he->source is the original vertex
new_he->twin()->set_is_equal_aux_data_in_target(0, true); new_he->twin()->set_is_equal_aux_data_in_target(0, true);
new_he->twin()->set_is_equal_aux_data_in_target(1, true); new_he->twin()->set_is_equal_aux_data_in_target(1, true);
new_he->twin()->set_has_equal_aux_data_in_target(0,!base->aux_has_no_data(org_he, 0)); new_he->twin()->set_has_equal_aux_data_in_target(0,!base->aux_has_no_data(org_he, 0));
new_he->twin()->set_has_equal_aux_data_in_target(1,!base->aux_has_no_data(org_he, 1)); new_he->twin()->set_has_equal_aux_data_in_target(1,!base->aux_has_no_data(org_he, 1));
new_he->twin()->set_has_equal_aux_data_in_target_and_face
(0, org_he->twin()->get_has_equal_aux_data_in_face(0));
new_he->twin()->set_has_equal_aux_data_in_target_and_face
(1, org_he->twin()->get_has_equal_aux_data_in_face(1));
} }
protected: protected:
Self *base; Self *base;
@ -2535,10 +2586,12 @@ protected:
// Write the discover time for a given vertex. // Write the discover time for a given vertex.
template <typename Vertex, typename Graph> template <typename Vertex, typename Graph>
void discover_vertex (Vertex fh, const Graph& g) void discover_vertex (Vertex fh, const Graph& g)
{ {
#ifdef CGAL_DEBUG_ENVELOPE_DEQ_3 #ifdef CGAL_DEBUG_ENVELOPE_DEQ_3
std::cout << "in BFS - found a face" << std::endl; std::cout << "in BFS - found a face" << std::endl;
#endif #endif
// first we check if we can set the decision immediately // first we check if we can set the decision immediately
// if a surface of one map doesn't exist, then we set the second surface // if a surface of one map doesn't exist, then we set the second surface