@@ -478,7 +478,18 @@ class Arr_halfedge : public H,
478478 const Inner_ccb* inner_ccb () const
479479 {
480480 CGAL_precondition (is_on_inner_ccb ());
481- return (reinterpret_cast <const Inner_ccb*>(_clean_pointer (this ->p_comp )));
481+
482+ const Inner_ccb* out = reinterpret_cast <const Inner_ccb*>(_clean_pointer (this ->p_comp ));
483+ if (out->is_valid ())
484+ return out;
485+
486+ // else reduce path and get valid iccb
487+ const Inner_ccb* valid = out->next ();
488+ while (!valid->is_valid ())
489+ valid = valid->next ();
490+ const_cast <Inner_ccb*>(out)->set_next (const_cast <Inner_ccb*>(valid));
491+ const_cast <Halfedge*>(this )->set_inner_ccb (valid);
492+ return valid;
482493 }
483494
484495 /* ! Get an incident inner CCB (non-const version).
@@ -487,11 +498,28 @@ class Arr_halfedge : public H,
487498 Inner_ccb* inner_ccb ()
488499 {
489500 CGAL_precondition (is_on_inner_ccb ());
490- return (reinterpret_cast <Inner_ccb*>(_clean_pointer (this ->p_comp )));
501+
502+ Inner_ccb* out = reinterpret_cast <Inner_ccb*>(_clean_pointer (this ->p_comp ));
503+ if (out->is_valid ())
504+ return out;
505+
506+ // else reduce path and get valid iccb
507+ Inner_ccb* valid = out->next ();
508+ while (!valid->is_valid ())
509+ valid = valid->next ();
510+ out->set_next (valid);
511+ set_inner_ccb (valid);
512+ return valid;
513+ }
514+
515+ Inner_ccb* inner_ccb_no_redirect ()
516+ {
517+ CGAL_precondition (is_on_inner_ccb ());
518+ return reinterpret_cast <Inner_ccb*>(_clean_pointer (this ->p_comp ));
491519 }
492520
493521 /* ! Set the incident inner CCB. */
494- void set_inner_ccb (Inner_ccb *ic)
522+ void set_inner_ccb (const Inner_ccb *ic)
495523 {
496524 // Set the component pointer and set its LSB.
497525 this ->p_comp = _set_lsb (ic);
@@ -768,57 +796,111 @@ class Arr_inner_ccb : public In_place_list_base<Arr_inner_ccb<V,H,F> >
768796 typedef typename Face::Inner_ccb_iterator Inner_ccb_iterator;
769797
770798private:
771- Face* p_f; // The face the contains the CCB in its interior.
799+ union
800+ {
801+ Face* f; // The face the contains the CCB in its interior.
802+ Arr_inner_ccb* icc; // next inner CCB in chain to valid icc
803+ } f_or_icc;
772804 Inner_ccb_iterator iter; // The inner CCB identifier.
773- bool iter_is_not_singular;
805+ enum
806+ {
807+ ITER_IS_SINGULAR, // singular = default iterator, not initialized
808+ ITER_IS_NOT_SINGULAR, // not singular = iterator was assigned and is valid
809+ INVALID // invalid = the inner CCB is invalid and
810+ // only links to another inner CCB
811+ // in chain to valid CCB
812+ } status;
774813
775814public:
776815 /* ! Default constructor. */
777- Arr_inner_ccb () : p_f( nullptr ), iter_is_not_singular( false ) { }
816+ Arr_inner_ccb () : status(ITER_IS_SINGULAR) { f_or_icc. f = nullptr ; }
778817
779818 /* ! Copy constructor. */
780819 Arr_inner_ccb (const Arr_inner_ccb& other) :
781- p_f (other.p_f ), iter_is_not_singular (other.iter_is_not_singular )
782- { if (other.iter_is_not_singular ) iter = other.iter ; }
820+ f_or_icc (other.f_or_icc ), status (other.status )
821+ { if (other.status == ITER_IS_NOT_SINGULAR ) iter = other.iter ; }
783822
784823 /* ! Get a halfedge along the component (const version). */
785- const Halfedge* halfedge () const { return (*iter); }
824+ const Halfedge* halfedge () const
825+ {
826+ CGAL_assertion (is_valid ());
827+ return (*iter);
828+ }
786829
787830 /* ! Get a halfedge along the component (non-const version). */
788- Halfedge* halfedge () { return (*iter); }
831+ Halfedge* halfedge ()
832+ {
833+ CGAL_assertion (is_valid ());
834+ return (*iter);
835+ }
789836
790837 /* ! Set a representative halfedge for the component. */
791- void set_halfedge (Halfedge *he) { *iter = he; }
838+ void set_halfedge (Halfedge *he)
839+ {
840+ CGAL_assertion (is_valid ());
841+ *iter = he;
842+ }
792843
793844 /* ! Get the incident face (const version). */
794- const Face* face () const { return (p_f); }
845+ const Face* face () const
846+ {
847+ CGAL_assertion (status != INVALID);
848+ return f_or_icc.f ;
849+ }
795850
796851 /* ! Get the incident face (non-const version). */
797- Face* face () { return (p_f); }
852+ Face* face ()
853+ {
854+ CGAL_assertion (status != INVALID);
855+ return f_or_icc.f ;
856+ }
798857
799858 /* ! Set the incident face. */
800- void set_face (Face* f) { p_f = f; }
859+ void set_face (Face* f)
860+ {
861+ CGAL_assertion (status != INVALID);
862+ f_or_icc.f = f;
863+ }
801864
802865 /* ! Get the iterator (const version). */
803866 Inner_ccb_iterator iterator () const
804867 {
805- CGAL_assertion (iter_is_not_singular );
868+ CGAL_assertion (status == ITER_IS_NOT_SINGULAR );
806869 return (iter);
807870 }
808871
809872 /* ! Get the iterator (non-const version). */
810873 Inner_ccb_iterator iterator ()
811874 {
812- CGAL_assertion (iter_is_not_singular );
875+ CGAL_assertion (status == ITER_IS_NOT_SINGULAR );
813876 return (iter);
814877 }
815878
816879 /* ! Set the inner CCB iterator. */
817880 void set_iterator (Inner_ccb_iterator it)
818881 {
882+ CGAL_assertion (is_valid ());
819883 iter = it;
820- iter_is_not_singular = true ;
884+ status = ITER_IS_NOT_SINGULAR;
885+ }
886+
887+ /* ! Check validity */
888+ bool is_valid () const { return (status != INVALID); }
889+
890+ /* ! Get the next CCB to primary chain. */
891+ Arr_inner_ccb* next () const
892+ {
893+ CGAL_assertion (status == INVALID);
894+ return f_or_icc.icc ;
821895 }
896+
897+ /* ! Set the next CCB to primary chain. */
898+ void set_next (Arr_inner_ccb* next)
899+ {
900+ status = INVALID;
901+ f_or_icc.icc = next;
902+ }
903+
822904};
823905
824906/* ! \class
@@ -942,6 +1024,7 @@ class Arr_dcel_base {
9421024 typedef typename Face_list::iterator Face_iterator;
9431025 typedef CGAL::N_step_adaptor_derived<Halfedge_iterator, 2 >
9441026 Edge_iterator;
1027+ typedef typename Inner_ccb_list::iterator Inner_ccb_iterator;
9451028
9461029 // Definitions of const iterators.
9471030 typedef typename Vertex_list::const_iterator Vertex_const_iterator;
@@ -1018,6 +1101,9 @@ class Arr_dcel_base {
10181101 {
10191102 return make_prevent_deref_range (edges_begin (), edges_end ());
10201103 }
1104+
1105+ Inner_ccb_iterator inner_ccbs_begin () { return in_ccbs.begin (); }
1106+ Inner_ccb_iterator inner_ccbs_end () { return in_ccbs.end (); }
10211107 // @}
10221108
10231109 // / \name Obtaining constant iterators.
0 commit comments