mirror of https://github.com/CGAL/cgal
When an edge is created inside a face of the other source map, with end vertex
that coincides with a vertex on the boundary of that face, we find the halfedge that points to the face and to the vertex, and update the is_equal/has_equal flags using this halfedge, whenever we can.
This commit is contained in:
parent
a9ff8f04a7
commit
72fd0fa130
|
|
@ -50,6 +50,21 @@ public:
|
|||
protected:
|
||||
|
||||
typedef typename Minimization_diagram_2::Dcel::Dcel_data_iterator Envelope_data_iterator;
|
||||
typedef std::pair<Vertex_handle, Face_handle> Vertex_face_pair;
|
||||
struct Less_vertex_face_pair
|
||||
{
|
||||
bool operator() (const Vertex_face_pair& vf1,
|
||||
const Vertex_face_pair& vf2) const
|
||||
{
|
||||
Vertex_handle v1 = vf1.first, v2 = vf2.first;
|
||||
Face_handle f1 = vf1.second, f2= vf2.second;
|
||||
return (&*v1 < &*v2 ||
|
||||
(&*v1 == &*v2 && &*f1 < &*f2));
|
||||
}
|
||||
};
|
||||
typedef std::map<Vertex_face_pair, Halfedge_handle,
|
||||
Less_vertex_face_pair> Boundary_cache;
|
||||
|
||||
public:
|
||||
|
||||
Envelope_overlay_functor(Minimization_diagram_2& md1,
|
||||
|
|
@ -58,6 +73,11 @@ public:
|
|||
: m_1(md1), m_2(md2), m_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
~Envelope_overlay_functor()
|
||||
{
|
||||
traversed_vertices.clear();
|
||||
}
|
||||
|
||||
void create_face (Face_const_handle1 f1, Face_const_handle2 f2, Res_face_handle res_f)
|
||||
{
|
||||
|
|
@ -244,7 +264,7 @@ public:
|
|||
res_h->set_aux_source(1, m_2.non_const_handle(f2));
|
||||
|
||||
res_h->twin()->set_aux_source(0, m_1.non_const_handle(h1->twin()));
|
||||
res_h->twin()->set_aux_source(1, m_2.non_const_handle(f2));
|
||||
res_h->twin()->set_aux_source(1, m_2.non_const_handle(f2));
|
||||
|
||||
res_h->set_is_equal_aux_data_in_face(0, h1->get_is_equal_data_in_face());
|
||||
res_h->set_is_equal_aux_data_in_face(1, true);
|
||||
|
|
@ -288,92 +308,10 @@ public:
|
|||
CGAL_assertion(false);
|
||||
|
||||
// update is_equal/has_equal data in target for the second source map
|
||||
Vertex_handle vh2;
|
||||
Halfedge_handle hh2;
|
||||
Face_handle fh2;
|
||||
// update target
|
||||
Object trg_src2 = res_h->target()->get_aux_source(1);
|
||||
if (assign(vh2, trg_src2))
|
||||
// todo
|
||||
{
|
||||
if (vh2->is_isolated())
|
||||
copy_halfedge_target_info_from_vertex_face_info(vh2, res_h, 1);
|
||||
else
|
||||
{
|
||||
// we have a vertex vh2 on the boundary of the face f2
|
||||
bool is_equal = vh2->is_equal_data(f2->begin_data(), f2->end_data());
|
||||
bool has_equal = vh2->has_equal_data(f2->begin_data(), f2->end_data());
|
||||
|
||||
res_h->set_is_equal_aux_data_in_target(1, is_equal);
|
||||
res_h->set_has_equal_aux_data_in_target(1, has_equal);
|
||||
}
|
||||
}
|
||||
else if (assign(hh2, trg_src2))
|
||||
// we should find the halfedge (hh2 or hh2->twin()) that points to face
|
||||
// f2, and check the in_face flags there
|
||||
{
|
||||
CGAL_assertion(hh2->face() == m_2.non_const_handle(f2) ||
|
||||
hh2->twin()->face() == m_2.non_const_handle(f2));
|
||||
Face_handle f = m_2.non_const_handle(f2);
|
||||
if (hh2->face() == f)
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh2, res_h, 1);
|
||||
else
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh2->twin(), res_h, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion(assign(fh2, trg_src2));
|
||||
assign(fh2, trg_src2);
|
||||
// the edge and target are in the same face, so we set halfedge-target
|
||||
// equal information to true, and has equal acoording to face data
|
||||
res_h->set_is_equal_aux_data_in_target(1, true);
|
||||
res_h->set_has_equal_aux_data_in_target(1, !fh2->has_no_data());
|
||||
// set_halfedge_target_info(res_h, 1, true);
|
||||
}
|
||||
|
||||
// update source
|
||||
Object src_src2 = res_h->source()->get_aux_source(1);
|
||||
if (assign(vh2, src_src2))
|
||||
// todo
|
||||
{
|
||||
// we have a vertex vh2 on the boundary of the face f2
|
||||
// or an isolated vertex
|
||||
if (vh2->is_isolated())
|
||||
copy_halfedge_target_info_from_vertex_face_info(vh2, res_h->twin(), 1);
|
||||
else
|
||||
{
|
||||
bool is_equal = vh2->is_equal_data(f2->begin_data(), f2->end_data());
|
||||
bool has_equal = vh2->has_equal_data(f2->begin_data(), f2->end_data());
|
||||
|
||||
res_h->twin()->set_is_equal_aux_data_in_target(1, is_equal);
|
||||
res_h->twin()->set_has_equal_aux_data_in_target(1, has_equal);
|
||||
}
|
||||
}
|
||||
else if (assign(hh2, src_src2))
|
||||
// we should find the halfedge (hh2 or hh2->twin()) that points to face
|
||||
// f2, and check the in_face flags there
|
||||
{
|
||||
CGAL_assertion(hh2->face() == m_2.non_const_handle(f2) ||
|
||||
hh2->twin()->face() == m_2.non_const_handle(f2));
|
||||
Face_handle f = m_2.non_const_handle(f2);
|
||||
if (hh2->face() == f)
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh2, res_h->twin(), 1);
|
||||
else
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh2->twin(), res_h->twin(), 1);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
CGAL_assertion(assign(fh2, src_src2));
|
||||
assign(fh2, src_src2);
|
||||
// the edge and soucre are in the same face, so we set halfedge-target
|
||||
// information to true
|
||||
res_h->twin()->set_is_equal_aux_data_in_target(1, true);
|
||||
res_h->twin()->set_has_equal_aux_data_in_target(1, !fh2->has_no_data());
|
||||
|
||||
// set_halfedge_target_info(res_h->twin(), 1, true);
|
||||
}
|
||||
|
||||
update_halfedge_flags_in_face(res_h, m_2.non_const_handle(f2), 1);
|
||||
|
||||
// update is_equal/has_equal data in source for the second source map
|
||||
update_halfedge_flags_in_face(res_h->twin(), m_2.non_const_handle(f2), 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -387,6 +325,7 @@ public:
|
|||
res_h->twin()->set_aux_source(0, m_1.non_const_handle(f1));
|
||||
res_h->twin()->set_aux_source(1, m_2.non_const_handle(h2->twin()));
|
||||
|
||||
// update halfedge-face flags of the new halfedge
|
||||
res_h->set_is_equal_aux_data_in_face(0, true);
|
||||
res_h->set_is_equal_aux_data_in_face(1, h2->get_is_equal_data_in_face());
|
||||
res_h->set_has_equal_aux_data_in_face(0, !f1->has_no_data());
|
||||
|
|
@ -429,90 +368,9 @@ public:
|
|||
CGAL_assertion(false);
|
||||
|
||||
// update is_equal/has_equal data in target for the first source map
|
||||
Vertex_handle vh1;
|
||||
Halfedge_handle hh1;
|
||||
Face_handle fh1;
|
||||
// update target
|
||||
Object trg_src1 = res_h->target()->get_aux_source(0);
|
||||
if (assign(vh1, trg_src1))
|
||||
// todo
|
||||
{
|
||||
if (vh1->is_isolated())
|
||||
copy_halfedge_target_info_from_vertex_face_info(vh1, res_h, 0);
|
||||
else
|
||||
{
|
||||
// we have a vertex vh1 on the boundary of the face f1
|
||||
bool is_equal = vh1->is_equal_data(f1->begin_data(), f1->end_data());
|
||||
bool has_equal = vh1->has_equal_data(f1->begin_data(), f1->end_data());
|
||||
|
||||
res_h->set_is_equal_aux_data_in_target(0, is_equal);
|
||||
res_h->set_has_equal_aux_data_in_target(0, has_equal);
|
||||
}
|
||||
}
|
||||
else if (assign(hh1, trg_src1))
|
||||
// we should find the halfedge (hh1 or hh1>twin()) that points to face
|
||||
// f1, and check the in_face flags there
|
||||
{
|
||||
CGAL_assertion(hh1->face() == m_1.non_const_handle(f1) ||
|
||||
hh1->twin()->face() == m_1.non_const_handle(f1));
|
||||
Face_handle f = m_1.non_const_handle(f1);
|
||||
if (hh1->face() == f)
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh1, res_h, 0);
|
||||
else
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh1->twin(), res_h, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion(assign(fh1, trg_src1));
|
||||
assign(fh1, trg_src1);
|
||||
// the edge and target are in the same face, so we set halfedge-target
|
||||
// information to true
|
||||
res_h->set_is_equal_aux_data_in_target(0, true);
|
||||
res_h->set_has_equal_aux_data_in_target(0, !fh1->has_no_data());
|
||||
// set_halfedge_target_info(res_h, 0, true);
|
||||
}
|
||||
|
||||
// update source
|
||||
Object src_src1 = res_h->source()->get_aux_source(0);
|
||||
if (assign(vh1, src_src1))
|
||||
// todo
|
||||
{
|
||||
if (vh1->is_isolated())
|
||||
copy_halfedge_target_info_from_vertex_face_info(vh1, res_h->twin(), 0);
|
||||
else
|
||||
{
|
||||
// we have a vertex vh1 on the boundary of the face f1
|
||||
bool is_equal = vh1->is_equal_data(f1->begin_data(), f1->end_data());
|
||||
bool has_equal = vh1->has_equal_data(f1->begin_data(), f1->end_data());
|
||||
|
||||
res_h->twin()->set_is_equal_aux_data_in_target(0, is_equal);
|
||||
res_h->twin()->set_has_equal_aux_data_in_target(0, has_equal);
|
||||
}
|
||||
}
|
||||
else if (assign(hh1, src_src1))
|
||||
// we should find the halfedge (hh1 or hh1->twin()) that points to face
|
||||
// f1, and check the in_face flags there
|
||||
{
|
||||
CGAL_assertion(hh1->face() == m_1.non_const_handle(f1) ||
|
||||
hh1->twin()->face() == m_1.non_const_handle(f1));
|
||||
Face_handle f = m_1.non_const_handle(f1);
|
||||
if (hh1->face() == f)
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh1, res_h->twin(), 0);
|
||||
else
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh1->twin(), res_h->twin(), 0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
CGAL_assertion(assign(fh1, src_src1));
|
||||
assign(fh1, src_src1);
|
||||
// the edge and soucre are in the same face, so we set halfedge-target
|
||||
// information to true
|
||||
res_h->twin()->set_is_equal_aux_data_in_target(0, true);
|
||||
res_h->twin()->set_has_equal_aux_data_in_target(0, !fh1->has_no_data());
|
||||
|
||||
// set_halfedge_target_info(res_h->twin(), 0, true);
|
||||
}
|
||||
update_halfedge_flags_in_face(res_h, m_1.non_const_handle(f1), 0);
|
||||
// update is_equal/has_equal data in source for the first source map
|
||||
update_halfedge_flags_in_face(res_h->twin(), m_1.non_const_handle(f1), 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -545,10 +403,125 @@ protected:
|
|||
to->set_is_equal_aux_data_in_target(id, from->get_is_equal_data_in_face());
|
||||
to->set_has_equal_aux_data_in_target(id, from->get_has_equal_data_in_face());
|
||||
}
|
||||
|
||||
// find a halfedge that v is its target and f is its face
|
||||
Halfedge_handle find_halfedge_by_vertex_and_face(Vertex_handle v, Face_handle f)
|
||||
{
|
||||
// should always invoke this method when v is on the boundary of f
|
||||
|
||||
// for the complexity of the total algorithm, we only loop over
|
||||
// the halfedges of each vertex once and cache the triples of
|
||||
// vertex-face-halfedge for future such questions
|
||||
Vertex_face_pair query(v, f);
|
||||
typename Boundary_cache::iterator iter = traversed_vertices.find(query);
|
||||
Halfedge_handle result;
|
||||
if (iter == traversed_vertices.end())
|
||||
{
|
||||
// first time to check this vertex - traverse all its halfedges
|
||||
// and update the map
|
||||
typename Minimization_diagram_2::Halfedge_around_vertex_circulator vc =
|
||||
v->incident_halfedges(),
|
||||
vc_begin = vc;
|
||||
do {
|
||||
Halfedge_handle hh = vc;
|
||||
// update the map
|
||||
traversed_vertices[Vertex_face_pair(v, hh->face())] = hh;
|
||||
// check for reult
|
||||
if (hh->face() == f)
|
||||
result = hh;
|
||||
++vc;
|
||||
} while (vc != vc_begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// take it from the map
|
||||
result = iter->second;
|
||||
}
|
||||
CGAL_assertion(result != Halfedge_handle());
|
||||
return result;
|
||||
}
|
||||
|
||||
// update halfedge-target flags of new_h that is created inside face in_face
|
||||
// id is the source diagram where in_face comes from
|
||||
// (i.e. the id of the aux information to update)
|
||||
void update_halfedge_flags_in_face(Halfedge_handle new_h, Face_handle in_face, unsigned int id)
|
||||
{
|
||||
// update is_equal/has_equal data in target for the first source map
|
||||
Vertex_handle vh;
|
||||
Halfedge_handle hh;
|
||||
Face_handle fh;
|
||||
// update target
|
||||
Object trg_src = new_h->target()->get_aux_source(id);
|
||||
if (assign(vh, trg_src))
|
||||
// todo
|
||||
{
|
||||
if (vh->is_isolated())
|
||||
copy_halfedge_target_info_from_vertex_face_info(vh, new_h, id);
|
||||
else
|
||||
{
|
||||
// we have a vertex vh on the boundary of the face in_face
|
||||
// todo: get rid of this calculations: (using unknown value for has_equal flag)
|
||||
CGAL_assertion_code(
|
||||
bool calc_is_equal = vh->is_equal_data(in_face->begin_data(), in_face->end_data());
|
||||
)
|
||||
bool calc_has_equal = vh->has_equal_data(in_face->begin_data(), in_face->end_data());
|
||||
|
||||
// find the halfedge with target vh on the boundary of in_face
|
||||
Halfedge_handle h_of_vh_and_in_face =
|
||||
find_halfedge_by_vertex_and_face(vh, in_face);
|
||||
// is_equal relationship is easy:
|
||||
bool is_equal = h_of_vh_and_in_face->get_is_equal_data_in_face() &&
|
||||
h_of_vh_and_in_face->get_is_equal_data_in_target();
|
||||
CGAL_assertion(is_equal == calc_is_equal);
|
||||
|
||||
// has_equal relationship is problematic in one case:
|
||||
bool has_equal;
|
||||
if (h_of_vh_and_in_face->get_has_equal_data_in_face() == true)
|
||||
has_equal = h_of_vh_and_in_face->get_has_equal_data_in_target();
|
||||
else
|
||||
if (h_of_vh_and_in_face->get_has_equal_data_in_target() == false)
|
||||
has_equal = false;
|
||||
else if (h_of_vh_and_in_face->get_is_equal_data_in_target() == true)
|
||||
has_equal = false;
|
||||
else
|
||||
{
|
||||
CGAL_assertion_code(std::cout << "happen" << std::endl;)
|
||||
has_equal = calc_has_equal;
|
||||
}
|
||||
CGAL_assertion(has_equal == calc_has_equal);
|
||||
|
||||
new_h->set_is_equal_aux_data_in_target(id, is_equal);
|
||||
new_h->set_has_equal_aux_data_in_target(id, calc_has_equal);
|
||||
}
|
||||
}
|
||||
else if (assign(hh, trg_src))
|
||||
// we should find the halfedge (hh or hh>twin()) that points to face
|
||||
// in_face, and check the halfedge-face flags there
|
||||
{
|
||||
CGAL_assertion(hh->face() == in_face || hh->twin()->face() == in_face);
|
||||
if (hh->face() == in_face)
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh, new_h, id);
|
||||
else
|
||||
copy_halfedge_target_info_from_halfedge_face_info(hh->twin(), new_h, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion_code(bool b =)
|
||||
assign(fh, trg_src);
|
||||
CGAL_assertion(b);
|
||||
// the edge and target are in the same face, so we set halfedge-target
|
||||
// is_equal information to true, and has_equal information according to
|
||||
// the face data
|
||||
CGAL_assertion(fh == in_face);
|
||||
new_h->set_is_equal_aux_data_in_target(id, true);
|
||||
new_h->set_has_equal_aux_data_in_target(id, !fh->has_no_data());
|
||||
}
|
||||
}
|
||||
|
||||
Minimization_diagram_2& m_1;
|
||||
Minimization_diagram_2& m_2;
|
||||
Minimization_diagram_2& m_result;
|
||||
Minimization_diagram_2& m_result;
|
||||
Boundary_cache traversed_vertices;
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
|
|
|||
Loading…
Reference in New Issue