mirror of https://github.com/CGAL/cgal
Sweep mode for Arrangement_2
This commit is contained in:
parent
2341612609
commit
2f9cdd068b
|
|
@ -482,11 +482,10 @@ public:
|
||||||
const Inner_ccb* out = reinterpret_cast<const Inner_ccb*>(_clean_pointer(this->p_comp));
|
const Inner_ccb* out = reinterpret_cast<const Inner_ccb*>(_clean_pointer(this->p_comp));
|
||||||
if (out->is_valid())
|
if (out->is_valid())
|
||||||
return out;
|
return out;
|
||||||
// else
|
|
||||||
while (!out->is_valid())
|
|
||||||
out = out->next();
|
|
||||||
const_cast<Halfedge*>(this)->set_inner_ccb(out);
|
|
||||||
|
|
||||||
|
// else
|
||||||
|
out = const_cast<Inner_ccb*>(out)->reduce_path();
|
||||||
|
const_cast<Halfedge*>(this)->set_inner_ccb(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,14 +499,19 @@ public:
|
||||||
Inner_ccb* out = reinterpret_cast<Inner_ccb*>(_clean_pointer(this->p_comp));
|
Inner_ccb* out = reinterpret_cast<Inner_ccb*>(_clean_pointer(this->p_comp));
|
||||||
if (out->is_valid())
|
if (out->is_valid())
|
||||||
return out;
|
return out;
|
||||||
// else
|
|
||||||
while (!out->is_valid())
|
|
||||||
out = out->next();
|
|
||||||
set_inner_ccb(out);
|
|
||||||
|
|
||||||
|
// else
|
||||||
|
out = out->reduce_path();
|
||||||
|
set_inner_ccb(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inner_ccb* inner_ccb_no_redirect()
|
||||||
|
{
|
||||||
|
CGAL_precondition(is_on_inner_ccb());
|
||||||
|
return reinterpret_cast<Inner_ccb*>(_clean_pointer(this->p_comp));
|
||||||
|
}
|
||||||
|
|
||||||
/*! Set the incident inner CCB. */
|
/*! Set the incident inner CCB. */
|
||||||
void set_inner_ccb(const Inner_ccb *ic)
|
void set_inner_ccb(const Inner_ccb *ic)
|
||||||
{
|
{
|
||||||
|
|
@ -809,13 +813,25 @@ public:
|
||||||
{ if (other.status == ITER_IS_NOT_SINGULAR) iter = other.iter; }
|
{ if (other.status == ITER_IS_NOT_SINGULAR) iter = other.iter; }
|
||||||
|
|
||||||
/*! Get a halfedge along the component (const version). */
|
/*! Get a halfedge along the component (const version). */
|
||||||
const Halfedge* halfedge() const { return (*iter); }
|
const Halfedge* halfedge() const
|
||||||
|
{
|
||||||
|
CGAL_assertion (is_valid());
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Get a halfedge along the component (non-const version). */
|
/*! Get a halfedge along the component (non-const version). */
|
||||||
Halfedge* halfedge() { return (*iter); }
|
Halfedge* halfedge()
|
||||||
|
{
|
||||||
|
CGAL_assertion (is_valid());
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Set a representative halfedge for the component. */
|
/*! Set a representative halfedge for the component. */
|
||||||
void set_halfedge(Halfedge *he) { *iter = he; }
|
void set_halfedge(Halfedge *he)
|
||||||
|
{
|
||||||
|
CGAL_assertion (is_valid());
|
||||||
|
*iter = he;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Get the incident face (const version). */
|
/*! Get the incident face (const version). */
|
||||||
const Face* face() const
|
const Face* face() const
|
||||||
|
|
@ -855,7 +871,7 @@ public:
|
||||||
/*! Set the inner CCB iterator. */
|
/*! Set the inner CCB iterator. */
|
||||||
void set_iterator(Inner_ccb_iterator it)
|
void set_iterator(Inner_ccb_iterator it)
|
||||||
{
|
{
|
||||||
CGAL_assertion (status != INVALID);
|
CGAL_assertion (is_valid());
|
||||||
iter = it;
|
iter = it;
|
||||||
status = ITER_IS_NOT_SINGULAR;
|
status = ITER_IS_NOT_SINGULAR;
|
||||||
}
|
}
|
||||||
|
|
@ -876,6 +892,15 @@ public:
|
||||||
status = INVALID;
|
status = INVALID;
|
||||||
f_or_icc.icc = next;
|
f_or_icc.icc = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Arr_inner_ccb* reduce_path()
|
||||||
|
{
|
||||||
|
if (is_valid())
|
||||||
|
return this;
|
||||||
|
// else
|
||||||
|
f_or_icc.icc = f_or_icc.icc->reduce_path();
|
||||||
|
return f_or_icc.icc;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \class
|
/*! \class
|
||||||
|
|
@ -999,6 +1024,7 @@ public:
|
||||||
typedef typename Face_list::iterator Face_iterator;
|
typedef typename Face_list::iterator Face_iterator;
|
||||||
typedef CGAL::N_step_adaptor_derived<Halfedge_iterator, 2>
|
typedef CGAL::N_step_adaptor_derived<Halfedge_iterator, 2>
|
||||||
Edge_iterator;
|
Edge_iterator;
|
||||||
|
typedef typename Inner_ccb_list::iterator Inner_ccb_iterator;
|
||||||
|
|
||||||
// Definitions of const iterators.
|
// Definitions of const iterators.
|
||||||
typedef typename Vertex_list::const_iterator Vertex_const_iterator;
|
typedef typename Vertex_list::const_iterator Vertex_const_iterator;
|
||||||
|
|
@ -1075,6 +1101,9 @@ public:
|
||||||
{
|
{
|
||||||
return make_prevent_deref_range(edges_begin(), edges_end());
|
return make_prevent_deref_range(edges_begin(), edges_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inner_ccb_iterator inner_ccbs_begin() { return in_ccbs.begin(); }
|
||||||
|
Inner_ccb_iterator inner_ccbs_end() { return in_ccbs.end(); }
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// \name Obtaining constant iterators.
|
/// \name Obtaining constant iterators.
|
||||||
|
|
|
||||||
|
|
@ -2739,14 +2739,22 @@ _insert_at_vertices(DHalfedge* he_to,
|
||||||
he1->set_inner_ccb(ic1);
|
he1->set_inner_ccb(ic1);
|
||||||
he2->set_inner_ccb(ic1);
|
he2->set_inner_ccb(ic1);
|
||||||
|
|
||||||
|
if (m_sweep_mode)
|
||||||
|
{
|
||||||
|
CGAL_assertion(ic1->is_valid());
|
||||||
|
CGAL_assertion(ic2->is_valid());
|
||||||
|
ic2->set_next(ic1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Make all halfedges along ic2 to point to ic1.
|
// Make all halfedges along ic2 to point to ic1.
|
||||||
DHalfedge* curr;
|
DHalfedge* curr;
|
||||||
|
|
||||||
for (curr = he2->next(); curr != he1; curr = curr->next())
|
for (curr = he2->next(); curr != he1; curr = curr->next())
|
||||||
curr->set_inner_ccb(ic1);
|
curr->set_inner_ccb(ic1);
|
||||||
|
|
||||||
// Delete the redundant inner CCB.
|
// Delete the redundant inner CCB.
|
||||||
_dcel().delete_inner_ccb(ic2);
|
_dcel().delete_inner_ccb(ic2);
|
||||||
|
}
|
||||||
|
|
||||||
// Notify the observers that we have merged the two inner CCBs.
|
// Notify the observers that we have merged the two inner CCBs.
|
||||||
_notify_after_merge_inner_ccb(fh, (Halfedge_handle(he1))->ccb());
|
_notify_after_merge_inner_ccb(fh, (Halfedge_handle(he1))->ccb());
|
||||||
|
|
|
||||||
|
|
@ -909,6 +909,14 @@ protected:
|
||||||
bool m_own_traits; // inidicates whether the geometry
|
bool m_own_traits; // inidicates whether the geometry
|
||||||
// traits should be freed up.
|
// traits should be freed up.
|
||||||
|
|
||||||
|
bool m_sweep_mode = false;
|
||||||
|
// sweep mode efficiently
|
||||||
|
// merges inner CCB but
|
||||||
|
// keeps invalid inner CCB
|
||||||
|
// and memory overhead that
|
||||||
|
// should be cleaned
|
||||||
|
// afterwards
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \name Constructors.
|
/// \name Constructors.
|
||||||
//@{
|
//@{
|
||||||
|
|
@ -939,6 +947,9 @@ public:
|
||||||
/*! Destructor. */
|
/*! Destructor. */
|
||||||
virtual ~Arrangement_on_surface_2();
|
virtual ~Arrangement_on_surface_2();
|
||||||
|
|
||||||
|
/*! Change mode. */
|
||||||
|
void set_sweep_mode (bool mode) { m_sweep_mode = mode; }
|
||||||
|
|
||||||
/*! Clear the arrangement. */
|
/*! Clear the arrangement. */
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -1516,6 +1527,37 @@ public:
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Cleans the inner CCB if sweep mode was used, by removing all
|
||||||
|
* non-valid inner CCBs
|
||||||
|
*/
|
||||||
|
void clean_inner_ccbs()
|
||||||
|
{
|
||||||
|
for (DHalfedge_iter he = _dcel().halfedges_begin();
|
||||||
|
he != _dcel().halfedges_end(); ++ he)
|
||||||
|
{
|
||||||
|
if (!he->is_on_inner_ccb())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DInner_ccb* ic1 = he->inner_ccb_no_redirect();
|
||||||
|
if (ic1->is_valid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DInner_ccb* ic2 = he->inner_ccb();
|
||||||
|
if (!ic2->halfedge()->is_on_inner_ccb()
|
||||||
|
|| ic2->halfedge()->inner_ccb_no_redirect() != ic2)
|
||||||
|
ic2->set_halfedge(&(*he));
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Dcel::Inner_ccb_iterator it = _dcel().inner_ccbs_begin();
|
||||||
|
while (it != _dcel().inner_ccbs_end())
|
||||||
|
{
|
||||||
|
typename Dcel::Inner_ccb_iterator current = it ++;
|
||||||
|
if (!current->is_valid())
|
||||||
|
_dcel().delete_inner_ccb(&*current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// \name Determining the boundary-side conditions.
|
/// \name Determining the boundary-side conditions.
|
||||||
//@{
|
//@{
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,9 @@ public:
|
||||||
/* A notification issued before the sweep process starts. */
|
/* A notification issued before the sweep process starts. */
|
||||||
inline void before_sweep();
|
inline void before_sweep();
|
||||||
|
|
||||||
|
/* A notification issued after the sweep process stops. */
|
||||||
|
inline void after_sweep();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* A notification invoked before the sweep-line starts handling the given
|
* A notification invoked before the sweep-line starts handling the given
|
||||||
* event.
|
* event.
|
||||||
|
|
@ -267,7 +270,21 @@ private:
|
||||||
// Notifies the helper that the sweep process now starts.
|
// Notifies the helper that the sweep process now starts.
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
void Arr_construction_ss_visitor<Hlpr, Vis>::before_sweep()
|
void Arr_construction_ss_visitor<Hlpr, Vis>::before_sweep()
|
||||||
{ m_helper.before_sweep(); }
|
{
|
||||||
|
m_helper.before_sweep();
|
||||||
|
m_arr->set_sweep_mode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// A notification issued after the sweep process stops.
|
||||||
|
template <typename Hlpr, typename Vis>
|
||||||
|
void Arr_construction_ss_visitor<Hlpr, Vis>::after_sweep()
|
||||||
|
{
|
||||||
|
m_arr->clean_inner_ccbs();
|
||||||
|
m_arr->set_sweep_mode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// A notification invoked before the sweep-line starts handling the given
|
// A notification invoked before the sweep-line starts handling the given
|
||||||
|
|
|
||||||
|
|
@ -552,6 +552,8 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
|
||||||
{
|
{
|
||||||
|
Base::after_sweep();
|
||||||
|
|
||||||
// Notify boundary vertices:
|
// Notify boundary vertices:
|
||||||
typename Vertex_map::iterator it;
|
typename Vertex_map::iterator it;
|
||||||
for (it = m_vertices_map.begin(); it != m_vertices_map.end(); ++it) {
|
for (it = m_vertices_map.begin(); it != m_vertices_map.end(); ++it) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue