Merge pull request #7927 from efifogel/Aos_2-observer-efif

Introduce Arr_observer<Arrangement_2>
This commit is contained in:
Laurent Rineau 2024-01-24 16:01:56 +01:00
commit c0b02c48d6
29 changed files with 2070 additions and 2581 deletions

View File

@ -5703,20 +5703,25 @@ objects, so that when one object changes state, all its dependents are
notified and updated automatically. The observed object does not know
anything about the observers. It merely "publishes" information about
changes when they occur. In our case observers can be attached to an
arrangement object. An attached observer receives notifications about
the changes this arrangement undergoes.
arrangement object.
An observer object, the type of which is an instance of the
`Arr_observer<Arrangement>` class template, stores a pointer to an
arrangement object. When the `Arr_observer<Arrangement>` class
template is instantiated, the `Arrangement` parameter must be
substituted with the type of the arrangement object. The observer
receives notifications <em>just before</em> a structural change occurs
in the arrangement and <em>immediately after</em> such a change takes
place. `Arr_observer` serves as a base class for other
observer classes and defines a set of virtual notification
functions, with default empty implementations. The set of functions
can be divided into three categories, as follows:
An observer object that observes changes in an arrangement object
stores a pointer to the attached arrangement object. It receives
notifications about the changes this arrangement undergoes. The
observer receives notifications <em>just before</em> a structural
change occurs in the arrangement and <em>immediately after</em> such a
change takes place. An observer object that observes changes in an
arrangement object of type `Arrangement` must be of a type derived
from `Arrangement::Observer`, which is an alias to
`Aos_observer<Arrangement_on_surface_2>`, where
`Arrangement_on_surface_2` is the type of the arrangement object or
its base type. An instance of `Aos_observer<>` serves as a base type
for other observer classes and defines a set of virtual notification
functions, with default empty implementations. You can also use the
template alias `Arr_observer<Arrangement_2>`, where `Arrangement_2` is
the type of the arrangement object in case it is derived from an
instance of the template `Arrangement_on_surface_2`. The set of
functions can be divided into three categories, as follows:
<OL>
@ -5782,10 +5787,10 @@ the call to `after_global_change()`.
</OL>
See the Reference Manual for a detailed specification of the
`Arr_observer` class template and the prototypes of all notification
`Aos_observer` class template and the prototypes of all notification
functions.
Each arrangement object stores a list of pointers to `Arr_observer`
Each arrangement object stores a list of pointers to `Aos_observer`
objects. This list may be empty, in which case the arrangement does
not have to notify any external class on the structural changes it
undergoes. If, however, there are observers associated with the
@ -5799,7 +5804,7 @@ invoked for each observer.
<!-- This allows for the nesting of \Index{observer} objects. -->
Concrete arrangement-observer classes should inherit from
`Arr_observer`. When an observer is constructed, it is attached to a
`Aos_observer`. When an observer is constructed, it is attached to a
valid arrangement supplied to the observed constructor, or
alternatively the observer can be attached to the arrangement at a
later time. When this happens, the observer object inserts itself
@ -5809,8 +5814,8 @@ thereafter. Subsequently, the observer object unregisters itself by
removing itself from this list just before it is destroyed. Most
concrete observer-classes do not need to use the full set of
notifications. Thus, the bodies of all notification methods defined in
the base class `Arr_observer` are empty. A concrete observer that
inherits from `Arr_observer` needs to override only the relevant
the base class `Aos_observer` are empty. A concrete observer that
inherits from `Aos_observer` needs to override only the relevant
notification methods. The remaining methods are invoked when
corresponding changes occur, but they do nothing.

View File

@ -0,0 +1,424 @@
namespace CGAL {
/*! \ingroup PkgArrangementOnSurface2Ref
*
* \anchor arr_refaos_obs
*
* `Aos_observer` serves as an abstract base class for all observer classes that
* are attached to an arrangement instance of type `Arrangement` and receive
* notifications from the arrangement. This base class handles the attachment
* of the observer to a given arrangement instance or to the detachment of the
* observer from this arrangement instance. It also gives a default empty
* implementation to all notification functions that are invoked by the
* arrangement to notify the observer on local or global changes it undergoes.
* The notification functions are all virtual functions, so they can be
* overridden by the concrete observer classes that inherit from `Aos_observer`.
*
* In order to implement a concrete arrangement observer-class, one simply needs
* to derive from `Aos_observer` and override the relevant notification
* functions. For example, if only face-split events are of interest, it is
* sufficient to override just `before_split_face()` (or just
* `after_split_face()`).
*/
template <typename Arrangement>
class Aos_observer {
public:
/// \name Types
/// @{
//! the type of the associated arrangement.
typedef unspecified_type Arrangement_2;
//! the point type.
typedef typename Arrangement_2::Point_2 Point_2;
//! the \f$x\f$-monotone curve type.
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
//! the type of a handle to an arrangement vertex.
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
//! the type of a handle to an arrangement halfedge.
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
//! the type of a handle to an arrangement face.
typedef typename Arrangement_2::Face_handle Face_handle;
/*! represents a connected component of the boundary (CCB), either an outer
* boundary or an inner boundary (the latter is also referred to as a hole).
*/
typedef typename Arrangement_2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
/// @}
/// \name Creation
/// @{
/*! constructs an observer that is unattached to any arrangement instance. */
Aos_observer();
/*! constructs an observer and attaches it to the given arrangement `arr`. */
Aos_observer(Arrangement_2& arr);
/// @}
/// \name Modifiers
/// @{
/*! attaches the observer to the given arrangement `arr`. */
void attach(Arrangement_2& arr);
/*! detaches the observer from its arrangement. */
void detach();
/// @}
/// \name Notifications on Global Arrangement Operations
/// @{
/*! issued just before the attached arrangement is assigned with the contents of another
* arrangement.
* \param arr The other arrangement. Notice that the arrangement type is the type used to
* instantiate the observer, which is conveniently defined as
* `Arrangement_2::Base_aos`.
*/
virtual void before_assign(const typename Arrangement_2::Base_aos& arr);
/*! issued immediately after the attached arrangement has been assigned with
* the contents of another arrangement.
*/
virtual void after_assign();
/*! issued just before the attached arrangement is cleared. */
virtual void before_clear();
/*! issued immediately after the attached arrangement has been cleared, so it
* now consists only of a the unbounded face `uf`.
*/
virtual void after_clear(Face_handle uf);
/*! issued just before a global function starts to modify the attached
* arrangement. It is guaranteed that no queries (especially no point-location
* queries) are issued until the termination of the global function is
* indicated by `after_global_change()`.
*/
virtual void before_global_change();
/*!
issued immediately after a global function has stopped modifying the
attached arrangement.
*/
virtual void after_global_change();
/// @}
/// \name Notifications on Attachment or Detachment
/// @{
/*! issued just before the observer is attached to the arrangement instance
* `arr`.
* \param arr The arrangement that is about to attach the observer. Notice
* that the arrangement type is the type used to instantiate the
* observer, which is conveniently defined as
* `Arrangement_2::Base_aos`.
*/
virtual void before_attach(const typename Arrangement_2::Base_aos& arr);
/*! issued immediately after the observer has been attached to an arrangement
* instance.
*/
virtual void after_attach();
/*! issued just before the observer is detached from its arrangement instance.
*/
virtual void before_detach();
/*! issued immediately after the observer has been detached from its
* arrangement instance.
*/
virtual void after_detach();
/// @}
/// \name Notifications on Local Changes in the Arrangement
/// @{
/*! issued just before a new vertex that corresponds to the point `p` is
* created.
*/
virtual void before_create_vertex(const Point_2& p);
/*! issued immediately after a new vertex `v` has been created. Note that the
* vertex still has no incident edges and is not connected to any other vertex.
*/
virtual void after_create_vertex(Vertex_handle v);
/*! issued just before a new vertex at infinity is created, `cv` is the curve
* incident to the surface boundary, `ind` is the relevant curve-end, `ps_x`
* is the boundary condition of the vertex in \f$x\f$ and `ps_y` is the
* boundary condition of the vertex in \f$y\f$.
*/
virtual void before_create_boundary_vertex(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! issued immediately after a new vertex `v` has been created. Note that the
* vertex still has no incident edges and is not connected to any other vertex.
*/
virtual void after_create_boundary_vertex(Vertex_handle v);
/*! issued just before a new edge that corresponds to the \f$x\f$-monotone
* curve `c` and connects the vertices `v1` and `v2` is created.
*/
virtual void before_create_edge(const X_monotone_curve_2& c,
Vertex_handle v1, Vertex_handle v2);
/*! issued immediately after a new edge `e` has been created. The halfedge
* that is sent to this function is always directed from `v1` to `v2` (see
* `before_create_edge()`).
*/
virtual void after_create_edge(Halfedge_handle e);
/*! issued just before a vertex `v` is modified to be associated with the point
* `p`.
*/
virtual void before_modify_vertex(Vertex_handle v, const Point_2& p);
/*! issued immediately after an existing vertex `v` has been modified. */
virtual void after_modify_vertex(Vertex_handle v);
/*! issued just before an edge `e` is modified to be associated with the
* \f$x\f$-monotone curve `c`.
*/
virtual void before_modify_edge(Halfedge_handle e,
const X_monotone_curve_2& c);
/*! issued immediately after an existing edge `e` has been modified. */
virtual void after_modify_edge(Halfedge_handle e);
/*! issued just before an edge `e` is split into two edges that should be
* associated with the \f$x\f$-monotone curves `c1` and `c2`. The vertex `v`
* corresponds to the split point, and will be used to separate the two
* resulting edges.
*/
virtual void before_split_edge(Halfedge_handle e, Vertex_handle v,
const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2);
/*! issued immediately after an existing edge has been split into the two
* given edges `e1` and `e2`.
*/
virtual void after_split_edge(Halfedge_handle e1, Halfedge_handle e2);
/*! issued just before a fictitious edge `e` is split into two. The vertex at
* infinity `v` corresponds to the split point, and will be used to separate
* the two resulting edges.
*/
virtual void before_split_fictitious_edge(Halfedge_handle e, Vertex_handle v);
/*! issued immediately after an existing fictitious edge has been split into
* the two given fictitious edges `e1` and `e2`.
*/
virtual void after_split_fictitious_edge(Halfedge_handle e1,
Halfedge_handle e2);
/*! issued just before a face `f` is split into two, as a result of the
* insertion of the edge `e` into the arrangement.
*/
virtual void before_split_face(Face_handle f, Halfedge_handle e);
/*! issued immediately after the existing face `f1` has been split, such that
* a portion of it now forms a new face `f2`. The flag `is_hole` designates
* whether `f2` forms a hole (an inner CCB) inside `f1`.
*/
virtual void after_split_face(Face_handle f1, Face_handle f2, bool is_hole);
/*! issued just before outer CCB `h` inside a face `f` is split into two, as a
* result of the removal of the edge `e` from the arrangement.
*/
virtual void before_split_outer_ccb(Face_handle f, Ccb_halfedge_circulator h,
Halfedge_handle e);
/*! issued immediately after an outer CCB of the face `f` has been split,
* resulting in the two holes `h1` and `h2`.
*/
virtual void after_split_outer_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2);
/*! issued just before an inner CCB `h` inside a face `f` is split into two,
* as a result of the removal of the edge `e` from the arrangement.
*/
virtual void before_split_inner_ccb(Face_handle f, Ccb_halfedge_circulator h,
Halfedge_handle e);
/*! issued immediately after an inner CCB of the face `f` has been split,
* resulting in the two inner CCBs (holes) `h1` and `h2`.
*/
virtual void after_split_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2);
/*! issued just before the edge `e` is inserted as a new outer CCB inside the
* face `f`.
*/
virtual void before_add_outer_ccb(Face_handle f, Halfedge_handle e);
/*! issued immediately after a new outer ccb `h` has been created. The outer
* ccb always consists of a single pair of twin halfedges.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator h);
/*! issued just before the edge `e` is inserted as a new inner CCB inside the
* face `f`.
*/
virtual void before_add_inner_ccb(Face_handle f, Halfedge_handle e);
/*! issued immediately after a new inner CCB `h` has been created. The inner
* CCB always consists of a single pair of twin halfedges.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator h);
/*! issued just before the vertex `v` is inserted as an isolated vertex inside
* the face `f`.
*/
virtual void before_add_isolated_vertex(Face_handle f, Vertex_handle v);
/*! issued immediately after the vertex `v` has been set as an isolated vertex.
*/
virtual void after_add_isolated_vertex(Vertex_handle v);
/*! issued just before the two edges `e1` and `e2` are merged to form a single
* edge that will be associated with the \f$x\f$-monotone curve `c`.
*/
virtual void before_merge_edge(Halfedge_handle e1, Halfedge_handle e2,
const X_monotone_curve_2& c);
/*! issued immediately after two edges have been merged to form the edge `e`.
*/
virtual void after_merge_edge(Halfedge_handle e);
/*! issued just before the two fictitious edges `e1` and `e2` are merged to
* form a single fictitious edge.
*/
virtual void before_merge_fictitious_edge(Halfedge_handle e1,
Halfedge_handle e2);
/*! issued immediately after two fictitious edges have been merged to form the
* fictitious edge `e`.
*/
virtual void after_merge_fictitious_edge(Halfedge_handle e);
/*! issued just before the two edges `f1` and `f2` are merged to form a single
* face, following the removal of the edge `e` from the arrangement.
*/
virtual void before_merge_face(Face_handle f1, Face_handle f2,
Halfedge_handle e);
/*! issued immediately after two faces have been merged to form the face `f`.
*/
virtual void after_merge_face(Face_handle f);
/*! issued just before two outer ccbs `h1` and `h2` inside the face `f` are
* merged to form a single connected component, following the insertion of the
* edge `e` into the arrangement.
*/
virtual void before_merge_outer_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2,
Halfedge_handle e);
/*! issued immediately after two outer cCBs have been merged to form a single
* outer CCB `h` inside the face `f`.
*/
virtual void after_merge_outer_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued just before two inner CCBs `h1` and `h2` inside the face `f` are
* merged to form a single connected component, following the insertion of the
* edge `e` into the arrangement.
*/
virtual void before_merge_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2,
Halfedge_handle e);
/*! issued immediately after two inner CCBs have been merged to form a single
* inner CCB `h` inside the face `f`.
*/
virtual void after_merge_inner_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued just before the outer CCB `h` is moved from one face to another.
* This can happen if the face `to_f` containing the outer CCB has just been
* split from `from_f`.
*/
virtual void before_move_outer_ccb(Face_handle from_f, Face_handle to_f,
Ccb_halfedge_circulator h);
/*! issued immediately after the outer CCB `h` has been moved to a new face.
*/
virtual void after_move_outer_ccb(Ccb_halfedge_circulator h);
/*! issued just before the inner CCB `h` is moved from one face to another.
* This can happen if the face `to_f` containing the inner CCB has just been
* split from `from_f`.
*/
virtual void before_move_inner_ccb(Face_handle from_f, Face_handle to_f,
Ccb_halfedge_circulator h);
/*! issued immediately after the inner CCB `h` has been moved to a new face.
*/
virtual void after_move_inner_ccb(Ccb_halfedge_circulator h);
/*! issued just before the isolated vertex `v` is moved from one face to
* another. This can happen if the face `to_f` containing the isolated vertex
* has just been split from `from_f`.
*/
virtual void before_move_isolated_vertex(Face_handle from_f,
Face_handle to_f, Vertex_handle v);
/*! issued immediately after the isolated vertex `v` has been moved to a new
* face.
*/
virtual void after_move_isolated_vertex(Vertex_handle v);
/*! issued just before the vertex `v` is removed from the arrangement. */
virtual void before_remove_vertex(Vertex_handle v);
/*! issued immediately after a vertex has been removed (and deleted) from the
* arrangement.
*/
virtual void after_remove_vertex();
/*! issued just before the edge `e` is removed from the arrangement. */
virtual void before_remove_edge(Halfedge_handle e);
/*! issued immediately after an edge has been removed (and deleted) from the
* arrangement.
*/
virtual void after_remove_edge();
/*! issued just before the outer ccb `f` is removed from inside the face `f`.
*/
virtual void before_remove_outer_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued immediately after a outer CCB has been removed (and deleted) from
* inside the face `f`.
*/
virtual void after_remove_outer_ccb(Face_handle f);
/*! issued just before the inner CCB `f` is removed from inside the face `f`.
*/
virtual void before_remove_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h);
/*! issued immediately after a inner CCB has been removed (and deleted) from
* inside the face `f`.
*/
virtual void after_remove_inner_ccb(Face_handle f);
/// @}
}; /* end Aos_observer */
} /* end namespace CGAL */

View File

@ -1,41 +1,37 @@
namespace CGAL {
/*!
\ingroup PkgArrangementOnSurface2Ref
`Arr_face_index_map` maintains a mapping of face handles of an
attached arrangement object to indices (of type `unsigned int`).
This class template is a model of the concept
`ReadablePropertyMap`. A mapping between face handles and indices
enables convenient usage of property-map classes supplied by `boost`.
For example, the property-map class templates
`boost::vector_property_map`, which is based on `std::vector`,
and `boost::iterator_property_map`, which can be used to implement
a property map based on a native \CC array, require the
user to supply a mapping such as `Arr_face_index_map`.
As new faces might be inserted into the attached arrangement, and
existing faces might be removed, the notification mechanism is used
to dynamically maintain the mapping of face handles to indices.
\cgalModels{DefaultConstructible,CopyConstructible,Assignable,ReadablePropertyMap}
\sa `Arr_observer<Arrangement>`
\sa `Arr_vertex_index_map<Arrangement>`
/*! \ingroup PkgArrangementOnSurface2Ref
*
* `Arr_face_index_map` maintains a mapping of face handles of an attached
* arrangement object to indices (of type `unsigned int`). This class template
* is a model of the concept `ReadablePropertyMap`. A mapping between face
* handles and indices enables convenient usage of property-map classes supplied
* by `boost`. For example, the property-map class templates
* `boost::vector_property_map`, which is based on `std::vector`, and
* `boost::iterator_property_map`, which can be used to implement a property map
* based on a native \CC array, require the user to supply a mapping such as
* `Arr_face_index_map`.
*
* As new faces might be inserted into the attached arrangement, and
* existing faces might be removed, the notification mechanism is used
* to dynamically maintain the mapping of face handles to indices.
*
* \cgalModels{DefaultConstructible,CopyConstructible,Assignable,ReadablePropertyMap}
*
* \sa `Arr_vertex_index_map<Arrangement>`
*/
template< typename Arrangement >
class Arr_face_index_map: public Arr_observer<Arrangement> {
template <typename Arrangement_>
class Arr_face_index_map: public Arrangement_::Observer {
public:
/// \name Types
/// @{
/*!
the type of the attached arrangement.
/*! the type of the attached arrangement.
*/
typedef Arrangement Arrangement_2;
typedef Arrangement_ Arrangement_2;
typedef typename Arrangement_2::Base_aos Base_aos;
typedef boost::readable_property_map_tag category;
@ -45,13 +41,11 @@ typedef unsigned int reference;
typedef Face_handle key_type;
/*!
The face handle type.
/*! The face handle type.
*/
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Base_aos::Face_handle Face_handle;
/*!
The type of mapping of faces to indices.
/*! The type of mapping of faces to indices.
*/
typedef Unique_hash_map<Face_handle, value_type> Index_map;
@ -60,18 +54,16 @@ typedef Unique_hash_map<Face_handle, value_type> Index_map;
/// \name Creation
/// @{
/*!
constructs a map that is unattached to any arrangement instance.
/*! constructs a map that is unattached to any arrangement instance.
*/
Arr_face_index_map();
/*!
constructs a map and attaches it to the given arrangement `arr`.
/*! constructs a map and attaches it to the given arrangement `arr`.
*/
Arr_face_index_map(Arrangement_2& arr);
Arr_face_index_map(Base_aos& arr);
/// @}
}; /* end Arr_accessor */
} /* end namespace CGAL */
} /* end namespace CGAL */

View File

@ -2,408 +2,14 @@ namespace CGAL {
/*! \ingroup PkgArrangementOnSurface2Ref
*
* \anchor arr_refarr_obs
*
* `Arr_observer` serves as an abstract base class for all observer classes that
* are attached to an arrangement instance of type `Arrangement` and receive
* notifications from the arrangement. This base class handles the attachment
* of the observer to a given arrangement instance or to the detachment of the
* observer from this arrangement instance. It also gives a default empty
* implementation to all notification functions that are invoked by the
* arrangement to notify the observer on local or global changes it undergoes.
* The notification functions are all virtual functions, so they can be
* overridden by the concrete observer classes that inherit from `Arr_observer`.
*
* In order to implement a concrete arrangement observer-class, one simply needs
* to derive from `Arr_observer` and override the relevant notification
* functions. For example, if only face-split events are of interest, it is
* sufficient to override just `before_split_face()` (or just
* `after_split_face()`).
* `Arr_observer<Arrangement_2>` is an alias for
* Aos_observer<Arrangement_on_surface_2>`,
* where `Arrangement_2` derives from `Arrangement_on_surface_2` and the latter
* is an instance of the template
* `CGAL::Arrangement_on_surface_2<GeometryTraits, TopologyTraits>`.
*/
template< typename Arrangement >
class Arr_observer {
public:
/// \name Types
/// @{
template <typename Arrangement_>
using Arr_observer = typename Arrangement_::Observer;
/*! the type of the associated arrangement. */
typedef unspecified_type Arrangement_2;
/*! the point type. */
typedef typename Arrangement_2::Point_2 Point_2;
/*! the \f$ x\f$-monotone curve type. */
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
/*! */
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
/*! */
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
/*! */
typedef typename Arrangement_2::Face_handle Face_handle;
/*! represents a connected component of the boundary (CCB), either an outer
* boundary or an inner boundary (the latter is also referred to as a hole).
*/
typedef typename Arrangement_2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
/// @}
/// \name Creation
/// @{
/*! constructs an observer that is unattached to any arrangement instance. */
Arr_observer();
/*! constructs an observer and attaches it to the given arrangement `arr`. */
Arr_observer(Arrangement_2& arr);
/// @}
/// \name Modifiers
/// @{
/*! attaches the observer to the given arrangement `arr`. */
void attach(Arrangement_2& arr);
/*! detaches the observer from its arrangement. */
void detach();
/// @}
/// \name Notifications on Global Arrangement Operations
/// @{
/*! issued just before the attached arrangement is assigned with the contents of
* another arrangement `arr`.
*/
virtual void before_assign(const Arrangement_2& arr);
/*! issued immediately after the attached arrangement has been assigned with the
* contents of another arrangement.
*/
virtual void after_assign();
/*! issued just before the attached arrangement is cleared. */
virtual void before_clear();
/*! issued immediately after the attached arrangement has been cleared, so it
* now consists only of a the unbounded face `uf`.
*/
virtual void after_clear(Face_handle uf);
/*! issued just before a global function starts to modify the attached
* arrangement. It is guaranteed that no queries (especially no point-location
* queries) are issued until the termination of the global function is indicated
* by `after_global_change()`.
*/
virtual void before_global_change();
/*!
issued immediately after a global function has stopped modifying the
attached arrangement.
*/
virtual void after_global_change();
/// @}
/// \name Notifications on Attachment or Detachment
/// @{
/*! issued just before the observer is attached to the arrangement instance
* `arr`.
*/
virtual void before_attach(const Arrangement_2& arr);
/*! issued immediately after the observer has been attached to an arrangement
* instance.
*/
virtual void after_attach();
/*! issued just before the observer is detached from its arrangement instance.
*/
virtual void before_detach();
/*! issued immediately after the observer has been detached from its arrangement
* instance.
*/
virtual void after_detach();
/// @}
/// \name Notifications on Local Changes in the Arrangement
/// @{
/*! issued just before a new vertex that corresponds to the point `p` is
* created.
*/
virtual void before_create_vertex(const Point_2& p);
/*! issued immediately after a new vertex `v` has been created. Note that the
* vertex still has no incident edges and is not connected to any other vertex.
*/
virtual void after_create_vertex(Vertex_handle v);
/*! issued just before a new vertex at infinity is created, `cv` is the curve
* incident to the surface boundary, `ind` is the relevant curve-end, `ps_x` is
* the boundary condition of the vertex in \f$ x\f$ and `ps_y` is the boundary
* condition of the vertex in \f$ y\f$.
*/
virtual void before_create_boundary_vertex(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! issued immediately after a new vertex `v` has been created. Note that the
* vertex still has no incident edges and is not connected to any other vertex.
*/
virtual void after_create_boundary_vertex(Vertex_handle v);
/*! issued just before a new edge that corresponds to the \f$ x\f$-monotone
* curve `c` and connects the vertices `v1` and `v2` is created.
*/
virtual void before_create_edge(const X_monotone_curve_2& c,
Vertex_handle v1, Vertex_handle v2);
/*! issued immediately after a new edge `e` has been created. The halfedge that
* is sent to this function is always directed from `v1` to `v2` (see above).
*/
virtual void after_create_edge(Halfedge_handle e);
/*! issued just before a vertex `v` is modified to be associated with the point
* `p`.
*/
virtual void before_modify_vertex(Vertex_handle v, const Point_2& p);
/*! issued immediately after an existing vertex `v` has been modified. */
virtual void after_modify_vertex(Vertex_handle v);
/*! issued just before an edge `e` is modified to be associated with the \f$
* x\f$-monotone curve `c`.
*/
virtual void before_modify_edge(Halfedge_handle e, const X_monotone_curve_2& c);
/*! issued immediately after an existing edge `e` has been modified. */
virtual void after_modify_edge(Halfedge_handle e);
/*! issued just before an edge `e` is split into two edges that should be
* associated with the \f$ x\f$-monotone curves `c1` and `c2`. The vertex `v`
* corresponds to the split point, and will be used to separate the two
* resulting edges.
*/
virtual void before_split_edge(Halfedge_handle e, Vertex_handle v,
const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2);
/*! issued immediately after an existing edge has been split into the two given
* edges `e1` and `e2`.
*/
virtual void after_split_edge(Halfedge_handle e1, Halfedge_handle e2);
/*! issued just before a fictitious edge `e` is split into two. The vertex at
* infinity `v` corresponds to the split point, and will be used to separate the
* two resulting edges.
*/
virtual void before_split_fictitious_edge(Halfedge_handle e, Vertex_handle v);
/*! issued immediately after an existing fictitious edge has been split into the
* two given fictitious edges `e1` and `e2`.
*/
virtual void after_split_fictitious_edge(Halfedge_handle e1, Halfedge_handle e2);
/*! issued just before a face `f` is split into two, as a result of the
* insertion of the edge `e` into the arrangement.
*/
virtual void before_split_face(Face_handle f, Halfedge_handle e);
/*! issued immediately after the existing face `f1` has been split, such that a
* portion of it now forms a new face `f2`. The flag `is_hole` designates
* whether `f2` forms a hole (an inner CCB) inside `f1`.
*/
virtual void after_split_face(Face_handle f1, Face_handle f2, bool is_hole);
/*! issued just before outer ccb `h` inside a face `f` is split into two, as a
* result of the removal of the edge `e` from the arrangement.
*/
virtual void before_split_outer_ccb(Face_handle f, Ccb_halfedge_circulator h,
Halfedge_handle e);
/*! issued immediately after an outer ccb of the face `f` has been split,
* resulting in the two holes `h1` and `h2`.
*/
virtual void after_split_outer_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2);
/*! issued just before an inner ccb `h` inside a face `f` is split into two, as
* a result of the removal of the edge `e` from the arrangement.
*/
virtual void before_split_inner_ccb(Face_handle f, Ccb_halfedge_circulator h,
Halfedge_handle e);
/*! issued immediately after an inner ccb of the face `f` has been split,
* resulting in the two inner CCBs (holes) `h1` and `h2`.
*/
virtual void after_split_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2);
/*! issued just before the edge `e` is inserted as a new outer ccb inside the
* face `f`.
*/
virtual void before_add_outer_ccb(Face_handle f, Halfedge_handle e);
/*! issued immediately after a new outer ccb `h` has been created. The outer ccb
* always consists of a single pair of twin halfedges.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator h);
/*! issued just before the edge `e` is inserted as a new inner ccb inside the
* face `f`.
*/
virtual void before_add_inner_ccb(Face_handle f, Halfedge_handle e);
/*! issued immediately after a new inner ccb `h` has been created. The inner ccb
* always consists of a single pair of twin halfedges.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator h);
/*! issued just before the vertex `v` is inserted as an isolated vertex inside
* the face `f`.
*/
virtual void before_add_isolated_vertex(Face_handle f, Vertex_handle v);
/*! issued immediately after the vertex `v` has been set as an isolated vertex.
*/
virtual void after_add_isolated_vertex(Vertex_handle v);
/*! issued just before the two edges `e1` and `e2` are merged to form a single
* edge that will be associated with the \f$ x\f$-monotone curve `c`.
*/
virtual void before_merge_edge(Halfedge_handle e1, Halfedge_handle e2,
const X_monotone_curve_2& c);
/*! issued immediately after two edges have been merged to form the edge `e`. */
virtual void after_merge_edge(Halfedge_handle e);
/*! issued just before the two fictitious edges `e1` and `e2` are merged to form
* a single fictitious edge.
*/
virtual void before_merge_fictitious_edge(Halfedge_handle e1,
Halfedge_handle e2);
/*! issued immediately after two fictitious edges have been merged to form the
* fictitious edge `e`.
*/
virtual void after_merge_fictitious_edge(Halfedge_handle e);
/*! issued just before the two edges `f1` and `f2` are merged to form a single
* face, following the removal of the edge `e` from the arrangement.
*/
virtual void before_merge_face(Face_handle f1, Face_handle f2,
Halfedge_handle e);
/*! issued immediately after two faces have been merged to form the face `f`. */
virtual void after_merge_face(Face_handle f);
/*! issued just before two outer ccbs `h1` and `h2` inside the face `f` are
* merged to form a single connected component, following the insertion of the
* edge `e` into the arrangement.
*/
virtual void before_merge_outer_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2,
Halfedge_handle e);
/*! issued immediately after two outer ccbs have been merged to form a single
* outer ccb `h` inside the face `f`.
*/
virtual void after_merge_outer_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued just before two inner ccbs `h1` and `h2` inside the face `f` are
* merged to form a single connected component, following the insertion of the
* edge `e` into the arrangement.
*/
virtual void before_merge_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h1,
Ccb_halfedge_circulator h2,
Halfedge_handle e);
/*! issued immediately after two inner ccbs have been merged to form a single
* inner ccb `h` inside the face `f`.
*/
virtual void after_merge_inner_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued just before the outer ccb `h` is moved from one face to another.
* This can happen if the face `to_f` containing the outer ccb has just been
* split from `from_f`.
*/
virtual void before_move_outer_ccb(Face_handle from_f, Face_handle to_f,
Ccb_halfedge_circulator h);
/*! issued immediately after the outer ccb `h` has been moved to a new face. */
virtual void after_move_outer_ccb(Ccb_halfedge_circulator h);
/*! issued just before the inner ccb `h` is moved from one face to another.
* This can happen if the face `to_f` containing the inner ccb has just been
* split from `from_f`.
*/
virtual void before_move_inner_ccb(Face_handle from_f, Face_handle to_f,
Ccb_halfedge_circulator h);
/*! issued immediately after the inner ccb `h` has been moved to a new face. */
virtual void after_move_inner_ccb(Ccb_halfedge_circulator h);
/*! issued just before the isolated vertex `v` is moved from one face to
* another. This can happen if the face `to_f` containing the isolated vertex
* has just been split from `from_f`.
*/
virtual void before_move_isolated_vertex(Face_handle from_f,
Face_handle to_f, Vertex_handle v);
/*! issued immediately after the isolated vertex `v` has been moved to a new
* face.
*/
virtual void after_move_isolated_vertex(Vertex_handle v);
/*! issued just before the vertex `v` is removed from the arrangement. */
virtual void before_remove_vertex(Vertex_handle v);
/*! issued immediately after a vertex has been removed (and deleted) from the
* arrangement.
*/
virtual void after_remove_vertex();
/*! issued just before the edge `e` is removed from the arrangement. */
virtual void before_remove_edge(Halfedge_handle e);
/*! issued immediately after an edge has been removed (and deleted) from the
* arrangement.
*/
virtual void after_remove_edge();
/*! issued just before the outer ccb `f` is removed from inside the face `f`. */
virtual void before_remove_outer_ccb(Face_handle f, Ccb_halfedge_circulator h);
/*! issued immediately after a outer ccb has been removed (and deleted) from
* inside the face `f`.
*/
virtual void after_remove_outer_ccb(Face_handle f);
/*! issued just before the inner ccb `f` is removed from inside the face `f`.
*/
virtual void before_remove_inner_ccb(Face_handle f,
Ccb_halfedge_circulator h);
/*! issued immediately after a inner ccb has been removed (and deleted) from
* inside the face `f`.
*/
virtual void after_remove_inner_ccb(Face_handle f);
/// @}
}; /* end Arr_observer */
} /* end namespace CGAL */
} // namespace CGAL

View File

@ -1,7 +1,6 @@
namespace CGAL {
/*!
* \ingroup PkgArrangementOnSurface2PointLocation
/*! \ingroup PkgArrangementOnSurface2PointLocation
*
* \anchor arr_reftri_pl
*
@ -23,7 +22,6 @@ namespace CGAL {
*/
template <typename Arrangement_>
class Arr_triangulation_point_location : public Arr_observer<Arrangement_>
{}
class Arr_triangulation_point_location : public Arrangement_::Observer {}
}

View File

@ -1,41 +1,37 @@
namespace CGAL {
/*!
\ingroup PkgArrangementOnSurface2Ref
`Arr_vertex_index_map` maintains a mapping of vertex handles of an
attached arrangement object to indices (of type `unsigned int`).
This class template is a model of the concept
`ReadablePropertyMap`. A mapping between vertex handles and indices
enables convenient usage of property-map classes supplied by `boost`.
For example, the property-map class templates
`boost::vector_property_map`, which is based on `std::vector`,
and `boost::iterator_property_map`, which can be used to implement
a property map based on a native \CC array, require the
user to supply a mapping such as `Arr_vertex_index_map`.
As new vertices might be inserted into the attached arrangement, and
existing vertices might be removed, the notification mechanism is used
to dynamically maintain the mapping of vertex handles to indices.
\cgalModels{DefaultConstructible,CopyConstructible,Assignable,ReadablePropertyMap}
\sa `Arr_observer<Arrangement>`
\sa `Arr_face_index_map<Arrangement>`
/*! \ingroup PkgArrangementOnSurface2Ref
*
* `Arr_vertex_index_map` maintains a mapping of vertex handles of an attached
* arrangement object to indices (of type `unsigned int`). This class template
* is a model of the concept `ReadablePropertyMap`. A mapping between vertex
* handles and indices enables convenient usage of property-map classes supplied
* by `boost`. For example, the property-map class templates
* `boost::vector_property_map`, which is based on `std::vector`, and
* `boost::iterator_property_map`, which can be used to implement a property map
* based on a native \CC array, require the user to supply a mapping such as
* `Arr_vertex_index_map`.
*
* As new vertices might be inserted into the attached arrangement, and
* existing vertices might be removed, the notification mechanism is used
* to dynamically maintain the mapping of vertex handles to indices.
*
* \cgalModels{DefaultConstructible,CopyConstructible,Assignable,ReadablePropertyMap}
*
* \sa `Arr_face_index_map<Arrangement>`
*/
template< typename Arrangement >
class Arr_vertex_index_map: public Arr_observer<Arrangement> {
template< typename Arrangement_>
class Arr_vertex_index_map: public Arrangement_::Observer {
public:
/// \name Types
/// @{
/*!
the type of the attached arrangement.
/*! the type of the attached arrangement.
*/
typedef Arrangement Arrangement_2;
typedef Arrangement_ Arrangement_2;
typedef typename Arrangement_2::Base_aos Base_aos;
typedef boost::readable_property_map_tag category;
@ -45,13 +41,11 @@ typedef unsigned int reference;
typedef Vertex_handle key_type;
/*!
The vertex handle type.
/*! The vertex handle type.
*/
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Base_aos::Vertex_handle Vertex_handle;
/*!
The type of mapping of vertices to indices.
/*! The type of mapping of vertices to indices.
*/
typedef Unique_hash_map<Vertex_handle, value_type> Index_map;
@ -60,23 +54,16 @@ typedef Unique_hash_map<Vertex_handle, value_type> Index_map;
/// \name Creation
/// @{
/*!
constructs a map that is unattached to any arrangement instance.
/*! constructs a map that is unattached to any arrangement instance.
*/
Arr_vertex_index_map();
/*!
constructs a map and attaches it to the given arrangement `arr`.
/*! constructs a map and attaches it to the given arrangement `arr`.
*/
Arr_vertex_index_map(Arrangement_2& arr);
Arr_vertex_index_map(Base_aos& arr);
/// @}
}; /* end Arr_accessor */
} /* end namespace CGAL */

View File

@ -199,7 +199,8 @@ implemented as peripheral classes or as free (global) functions.
- `CGAL::Arrangement_2<Traits,Dcel>`
- `CGAL::Arrangement_with_history_2<Traits,Dcel>`
- `CGAL::Arr_accessor<Arrangement>`
- `CGAL::Arr_observer<Arrangement>`
- `CGAL::Aos_observer<ArrangementOnSurface_2>`
- `CGAL::Arr_observer<Arrangement_2>`
- `CGAL::Arrangement_2::Vertex`
- `CGAL::Arrangement_2::Halfedge`
- `CGAL::Arrangement_2::Face`

View File

@ -18,7 +18,8 @@ private:
public:
Face_index_observer(Ex_arrangement& arr) :
CGAL::Arr_observer<Ex_arrangement>(arr), n_faces(0)
CGAL::Arr_observer<Ex_arrangement>(arr),
n_faces(0)
{
CGAL_precondition(arr.is_empty());
arr.unbounded_face()->set_data (0);

View File

@ -55,22 +55,6 @@ int main() {
// Landmarks_pl landmarks_pl(gm);
Walk_pl walk_pl(gm);
// Trap_pl trap_pl(gm);
/* Need to add the code below to both Arr_spherical_gaussian_map_3 and
* Arr_polyhedral_sgm, and then work on the trap point location code...
private:
friend class Arr_observer<Self>;
friend class Arr_accessor<Self>;
protected:
typedef Arr_observer<Self> Observer;
void _register_observer(Observer *p_obs)
{ Base::_register_observer((typename Base::Observer*)p_obs); }
bool _unregister_observer(Observer *p_obs)
{ return (Base::_unregister_observer ((typename Base::Observer*)p_obs)); }
*/
Gm_traits traits;
Gm_initializer gm_initializer(gm);

View File

@ -0,0 +1,571 @@
// Copyright (c) 2006,2007,2009,2010,2011 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_AOS_OBSERVER_H
#define CGAL_AOS_OBSERVER_H
#include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/disable_warnings.h>
#include <CGAL/Arr_enums.h>
/*! \file
* Definition of the `Aos_observer<Arrangement>` base class.
*/
namespace CGAL {
/*! \class
* A base class for arrangement observers.
* The Arrangement parameter corresponds to an arrangement instantiation.
*/
template <typename Arrangement_>
class Aos_observer {
public:
typedef Arrangement_ Arrangement_2;
typedef Aos_observer<Arrangement_2> Self;
typedef typename Arrangement_2::Point_2 Point_2;
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
private:
Arrangement_2* p_arr; // The associated arrangement.
/*! Copy constructor - not supported. */
Aos_observer(const Self&);
/*! Assignment operator - not supported. */
Self& operator=(const Self&);
public:
/// \name Construction and destruction functions.
//@{
/*! Default constructor. */
Aos_observer() : p_arr(nullptr) {}
/*! Constructor with an associated arrangement. */
Aos_observer(Arrangement_2& arr) : p_arr(&arr)
{
// Register the observer object in the arrangement.
p_arr->_register_observer(this);
}
/*! Destructor. */
virtual ~Aos_observer()
{
// Unregister the observer object from the arrangement.
if (p_arr != nullptr)
p_arr->_unregister_observer(this);
}
//@}
/// \name Modifying the associated arrangement.
//@{
/*! Get the associated arrangement (const version). */
const Arrangement_2* arrangement() const { return (p_arr); }
/*! Get the associated arrangement (non-const version). */
Arrangement_2* arrangement() { return (p_arr); }
/*! Attach the observer to an arrangement.
* \pre The observer is not already attached to an arrangement.
*/
void attach(Arrangement_2& arr)
{
// Do nothing if the associated arrangement is not changed.
if (p_arr == &arr) return;
// The observer is not already attached to an arrangement.
CGAL_precondition (p_arr == nullptr);
if (p_arr != nullptr) return;
// Notify the concrete observer (the sub-class) about the attachment.
before_attach(arr);
// Register the observer object in the new arrangement.
p_arr = &arr;
p_arr->_register_observer(this);
// Notify the concrete observer that the attachment took place.
after_attach();
}
/*! Detach the observer from the arrangement. */
void detach()
{
if (p_arr == nullptr) return;
// Notify the concrete observer (the sub-class) about the detachment.
before_detach ();
// Unregister the observer object from the current arrangement, and mark
// that the observer is not attached to an arrangement.
p_arr->_unregister_observer(this);
p_arr = nullptr;
// Notify the concrete observer that the detachment took place.
after_detach();
}
//@}
/// \name Notification functions on global arrangement operations.
//@{
/*! Notification before the arrangement is assigned with another
* arrangement.
* \param arr The arrangement to be copied.
*/
virtual void before_assign(const Arrangement_2& /* arr */) {}
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign() {}
/*! Notification before the arrangement is cleared. */
virtual void before_clear() {}
/*! Notification after the arrangement is cleared. */
virtual void after_clear() {}
/*! Notification before a global operation modifies the arrangement. */
virtual void before_global_change() {}
/*! Notification after a global operation is completed. */
virtual void after_global_change() {}
//@}
/// \name Notification functions on observer attachment or detachment.
//@{
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement that is about to attach the observer.
*/
virtual void before_attach(const Arrangement_2& /* arr */) {}
/*! Notification after the observer has been attached to an arrangement. */
virtual void after_attach() {}
/*! Notification before the observer is detached from the arrangement. */
virtual void before_detach() {}
/*! Notification after the observer has been detached from the arrangement. */
virtual void after_detach() {}
//@}
/// \name Notification functions on local changes in the arrangement.
//@{
/*! Notification before the creation of a new vertex.
* \param p The point to be associated with the vertex.
* This point cannot lie on the surface boundaries.
*/
virtual void before_create_vertex(const Point_2& /* p */) {}
/*! Notification after the creation of a new vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_vertex(Vertex_handle /* v */)
{}
/*! Notification before the creation of a new boundary vertex.
* \param p The point on the surface boundary.
* \param ps_x The boundary condition of the vertex in x.
* \param ps_y The boundary condition of the vertex in y.
*/
virtual void before_create_boundary_vertex(const Point_2& /* p */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{}
/*! Notification before the creation of a new boundary vertex.
* \param cv The curve incident to the surface boundary.
* \param ind The relevant curve-end.
* \param ps_x The boundary condition of the vertex in x.
* \param ps_y The boundary condition of the vertex in y.
*/
virtual void before_create_boundary_vertex(const X_monotone_curve_2& /* cv */,
Arr_curve_end /* ind */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{}
/*! Notification after the creation of a new vertex at infinity.
* \param v A handle to the created vertex.
*/
virtual void after_create_boundary_vertex(Vertex_handle /* v */) {}
/*! Notification before the creation of a new edge.
* \param c The \f$x\f$-monotone curve to be associated with the edge.
* \param v1 A handle to the first end-vertex of the edge.
* \param v2 A handle to the second end-vertex of the edge.
*/
virtual void before_create_edge(const X_monotone_curve_2& /* c */,
Vertex_handle /* v1 */,
Vertex_handle /* v2 */)
{}
/*! Notification after the creation of a new edge.
* \param e A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge(Halfedge_handle /* e */) {}
/*! Notification before the modification of an existing vertex.
* \param v A handle to the vertex to be updated.
* \param p The point to be associated with the vertex.
*/
virtual void before_modify_vertex(Vertex_handle /* v */,
const Point_2& /* p */)
{}
/*! Notification after a vertex was modified.
* \param v A handle to the updated vertex.
*/
virtual void after_modify_vertex(Vertex_handle /* v */) {}
/*! Notification before the modification of an existing edge.
* \param e A handle to one of the twin halfedges to be updated.
* \param c The \f$x\f$-monotone curve to be associated with the edge.
*/
virtual void before_modify_edge(Halfedge_handle /* e */,
const X_monotone_curve_2& /* c */)
{}
/*! Notification after an edge was modified.
* \param e A handle to one of the twin halfedges that were updated.
*/
virtual void after_modify_edge(Halfedge_handle /* e */) {}
/*! Notification before the splitting of an edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the split point.
* \param c1 The \f$x\f$-monotone curve to be associated with the first edge.
* \param c2 The \f$x\f$-monotone curve to be associated with the second edge.
*/
virtual void before_split_edge(Halfedge_handle /* e */,
Vertex_handle /* v */,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */)
{}
/*! Notification after an edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification before the splitting of a fictitious edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the unbounded split point.
*/
virtual void before_split_fictitious_edge(Halfedge_handle /* e */,
Vertex_handle /* v */)
{}
/*! Notification after a fictitious edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification before the splitting of a face into two.
* \param f A handle to the existing face.
* \param e The new edge whose insertion causes the face to split.
*/
virtual void before_split_face(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after a face was split.
* \param f A handle to the face we have just split.
* \param new_f A handle to the new face that has been created.
* \param is_hole Whether the new face forms a hole inside f.
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{}
/*! Notification before the splitting of an outer CCB into two.
* \param f A handle to the face that owns the outer CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the outer CCB to split.
*/
virtual void before_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was split.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{}
/*! Notification before the splitting of an inner CCB into two.
* \param f A handle to the face containing the inner CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the inner CCB to split.
*/
virtual void before_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was split.
* \param f A handle to the face containing the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{}
/*! Notification before the creation of a new outer CCB of a face.
* \param f A handle to the face that owns the outer CCB.
* \param e A halfedge along the new outer CCB.
*/
virtual void before_add_outer_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was added to a face.
* \param h A circulator representing the boundary of the new outer CCB.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before the creation of a new inner CCB inside a face.
* \param f A handle to the face containing the inner CCB.
* \param e The new halfedge that forms the new inner CCB.
*/
virtual void before_add_inner_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was created inside a face.
* \param h A circulator representing the boundary of the new inner CCB.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before the creation of a new isolated vertex inside a face.
* \param f A handle to the face containing the isolated vertex.
* \param v The isolated vertex.
*/
virtual void before_add_isolated_vertex(Face_handle /* f */,
Vertex_handle /* v */)
{}
/*! Notification after an isolated vertex was created inside a face.
* \param v The isolated vertex.
*/
virtual void after_add_isolated_vertex(Vertex_handle /* v */) {}
/*! Notification before the merging of two edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
* \param c The \f$x\f$-monotone curve to be associated with the merged edge.
*/
virtual void before_merge_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */,
const X_monotone_curve_2& /* c */)
{}
/*! Notification after an edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge(Halfedge_handle /* e */) {}
/*! Notification before the merging of two fictitious edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
*/
virtual void before_merge_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification after a fictitious edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_fictitious_edge(Halfedge_handle /* e */) {}
/*! Notification before the merging of two faces.
* \param f1 A handle to the first face.
* \param f2 A handle to the second face.
* \param e The edge whose removal causes the faces to merge.
*/
virtual void before_merge_face(Face_handle /* f1 */,
Face_handle /* f2 */,
Halfedge_handle /* e */)
{}
/*! Notification after a face was merged.
* \param f A handle to the merged face.
*/
virtual void after_merge_face(Face_handle /* f */) {}
/*! Notification before the merging of two outer CCBs.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
* \param e The edge whose insertion or removal causes the CCBs to merge.
*/
virtual void before_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was merged.
* \param f A handle to the face that owns the outer CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification before the merging of two inner CCBs (holes).
* \param f A handle to the face that contains the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
* \param e The edge whose insertion causes the inner CCBs to merge.
*/
virtual void before_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was merged.
* \param f A handle to the face that contains the inner CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification before an outer CCB is moved from one face to another.
* \param from_f A handle to the face that currently owns the outer CCB.
* \param to_f A handle to the face that should own the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_outer_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification after an outer CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before an inner CCB is moved from one face to another.
* \param from_f A handle to the face currently containing the inner CCB.
* \param to_f A handle to the face that should contain the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_inner_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{}
/*!
* Notification after an inner CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before an isolated vertex is moved from one face to another.
* \param from_f A handle to the face currently containing the vertex.
* \param to_f A handle to the face that should contain the vertex.
* \param v The isolated vertex.
*/
virtual void before_move_isolated_vertex(Face_handle /* from_f */,
Face_handle /* to_f */,
Vertex_handle /* v */)
{}
/*! Notification after an isolated vertex is moved from one face to another.
* \param v The isolated vertex.
*/
virtual void after_move_isolated_vertex(Vertex_handle /* v */) {}
/*! Notificaion before the removal of a vertex.
* \param v A handle to the vertex to be deleted.
*/
virtual void before_remove_vertex(Vertex_handle /* v */) {}
/*! Notificaion after the removal of a vertex. */
virtual void after_remove_vertex() {}
/*! Notification before the removal of an edge.
* \param e A handle to one of the twin halfedges to be deleted.
*/
virtual void before_remove_edge(Halfedge_handle /* e */) {}
/*! Notificaion after the removal of an edge. */
virtual void after_remove_edge() {}
/*! Notification before the removal of an outer CCB.
* \param f The face that owns the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notificaion after the removal of an outer CCB.
* \param f The face that used to own the outer CCB.
*/
virtual void after_remove_outer_ccb(Face_handle /* f */) {}
/*! Notification before the removal of an inner CCB.
* \param f The face containing the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notificaion after the removal of an inner CCB.
* \param f The face that used to contain the inner CCB.
*/
virtual void after_remove_inner_ccb(Face_handle /* f */) {}
//@}
};
} //namespace CGAL
#include <CGAL/enable_warnings.h>
#endif

View File

@ -21,7 +21,6 @@
* Definition of the Arr_face_index_map<Arrangement> class.
*/
#include <CGAL/Arr_observer.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/property_map.h>
@ -34,26 +33,26 @@ namespace CGAL {
* arrangement faces to the indices 0, ..., (n -1), where n is the number
* of faces in the arrangement.
*/
template <class Arrangement_>
class Arr_face_index_map : public Arr_observer<Arrangement_>
{
template <typename Arrangement_>
class Arr_face_index_map : public Arrangement_::Observer {
public:
using Arrangement_2 = Arrangement_;
using Base_aos = typename Arrangement_2::Base_aos;
typedef Arrangement_ Arrangement_2;
typedef typename Arrangement_2::Face_handle Face_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using Face_handle = typename Base_aos::Face_handle;
// Boost property type definitions:
typedef boost::readable_property_map_tag category;
typedef unsigned int value_type;
typedef value_type reference;
typedef Face_handle key_type;
using category = boost::readable_property_map_tag;
using value_type = unsigned int;
using reference = value_type;
using key_type = Face_handle;
private:
using Self = Arr_face_index_map<Arrangement_2>;
using Base = typename Arrangement_2::Observer;
typedef Arr_face_index_map<Arrangement_2> Self;
typedef Arr_observer<Arrangement_2> Base;
typedef Unique_hash_map<Face_handle, unsigned int> Index_map;
using Index_map = Unique_hash_map<Face_handle, unsigned int>;
// Data members:
unsigned int n_faces; // The current number of faces.
@ -63,7 +62,6 @@ private:
enum {MIN_REV_MAP_SIZE = 32};
public:
/*! Default constructor. */
Arr_face_index_map() :
Base(),
@ -72,102 +70,73 @@ public:
{}
/*! Constructor with an associated arrangement. */
Arr_face_index_map (const Arrangement_2& arr) :
Base (const_cast<Arrangement_2&> (arr))
{
_init();
}
Arr_face_index_map(const Base_aos& arr) :
Base(const_cast<Base_aos&>(arr))
{ _init(); }
/*! Copy constructor. */
Arr_face_index_map(const Self& other) :
Base (const_cast<Arrangement_2&> (*(other.arrangement())))
{
_init();
}
Base(const_cast<Base_aos&>(*(other.arrangement())))
{ _init(); }
/*! Assignment operator. */
Self& operator= (const Self& other)
{
if (this == &other)
return (*this);
Self& operator= (const Self& other) {
if (this == &other) return (*this);
this->detach();
this->attach (const_cast<Arrangement_2&> (*(other.arrangement())));
this->attach(const_cast<Base_aos&>(*(other.arrangement())));
return (*this);
}
/*!
* Get the index of a given face.
/*! Get the index of a given face.
* \param f A handle to the face.
* \pre f is a valid face in the arrangement.
*/
unsigned int operator[] (Face_handle f) const
{
return (index_map[f]);
}
unsigned int operator[](Face_handle f) const { return (index_map[f]); }
/*!
* Get the face given its index.
/*! Get the face given its index.
* \param i The index of the face.
* \pre i is less than the number of faces in the arrangement.
*/
Face_handle face (const int i) const
{
Face_handle face(const int i) const {
CGAL_precondition((unsigned int) i < n_faces);
return (rev_map[i]);
}
/// \name Notification functions, to keep the mapping up-to-date.
//@{
/*!
* Update the mapping after the arrangement has been assigned with another
/*! Update the mapping after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign ()
{
_init();
}
virtual void after_assign() override { _init(); }
/*!
* Update the mapping after the arrangement is cleared.
/*! Update the mapping after the arrangement is cleared.
*/
virtual void after_clear ()
{
_init();
}
virtual void after_clear() override { _init(); }
/*!
* Update the mapping after attaching to a new arrangement.
/*! Update the mapping after attaching to a new arrangement.
*/
virtual void after_attach ()
{
_init();
}
virtual void after_attach() override { _init(); }
/*!
* Update the mapping after detaching the arrangement.
/*! Update the mapping after detaching the arrangement.
*/
virtual void after_detach ()
{
virtual void after_detach() override {
n_faces = 0;
index_map.clear();
}
/*!
* Update the mapping after the creation of a new face is split from another
/*! Update the mapping after the creation of a new face is split from another
* face.
* \param f A handle to the existing face.
* \param new_f A handle to the newly created face.
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle new_f,
bool /* is_hole */)
{
bool /* is_hole */) override {
// Update the number of vertices.
n_faces++;
++n_faces;
// If necessary, allocate memory for the reverse mapping.
if (rev_map.size() < n_faces)
@ -176,22 +145,17 @@ public:
// Update the mapping of the newly created face.
index_map[new_f] = n_faces - 1;
rev_map[n_faces - 1] = new_f;
return;
}
/*!
* Update the mapping before the merge of two faces.
/*! Update the mapping before the merge of two faces.
* \param f1 A handle to the face that is going to remain.
* \param f2 A handle to the face that is about to be removed.
*/
virtual void before_merge_face(Face_handle /* f1 */,
Face_handle f2,
typename
Arrangement_2::Halfedge_handle /* e */)
{
Halfedge_handle /* e */) override {
// Update the number of faces.
n_faces--;
--n_faces;
// Reduce memory consumption in case the number of faces has
// drastically decreased.
@ -205,8 +169,7 @@ public:
// currently indexed (n - 1).
unsigned int index = index_map[f2];
if (index == n_faces)
return;
if (index == n_faces) return;
Face_handle last_f = rev_map[n_faces];
index_map[last_f] = index;
@ -214,59 +177,45 @@ public:
// Clear the reverse mapping for the last face.
rev_map[n_faces] = Face_handle();
return;
}
//@}
private:
/*! Initialize the map for the given arrangement. */
void _init ()
{
void _init() {
// Get the number of faces and allocate the reverse map accordingly.
n_faces = static_cast<unsigned int>(this->arrangement()->number_of_faces());
if (n_faces < MIN_REV_MAP_SIZE)
rev_map.resize (MIN_REV_MAP_SIZE);
else
rev_map.resize (n_faces);
if (n_faces < MIN_REV_MAP_SIZE) rev_map.resize (MIN_REV_MAP_SIZE);
else rev_map.resize (n_faces);
// Clear the current mapping.
index_map.clear();
// Create the initial mapping.
typename Arrangement_2::Face_iterator fit;
Face_handle fh;
unsigned int index = 0;
for (fit = this->arrangement()->faces_begin();
fit != this->arrangement()->faces_end(); ++fit, ++index)
{
for (auto fit = this->arrangement()->faces_begin();
fit != this->arrangement()->faces_end(); ++fit, ++index) {
// Map the current face to the current index.
fh = fit;
index_map[fh] = index;
rev_map[index] = fh;
}
return;
}
};
/*!
* Get the index property-map function. Provided so that boost is able to
/*! Get the index property-map function. Provided so that boost is able to
* access the Arr_face_index_map above.
* \param index_map The index map.
* \param f A face handle.
* \return The face index.
*/
template<class Arrangement>
template <typename Arrangement>
unsigned int get(const CGAL::Arr_face_index_map<Arrangement>& index_map,
typename Arrangement::Face_handle f)
{
return (index_map[f]);
}
{ return (index_map[f]); }
} //namespace CGAL

View File

@ -1,4 +1,4 @@
// Copyright (c) 2006,2007,2009,2010,2011 Tel-Aviv University (Israel).
// Copyright (c) 2023 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
@ -8,563 +8,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ARR_OBSERVER_H
#define CGAL_ARR_OBSERVER_H
/*! \file
* Definition of the `Arr_observer<Arrangement>` base class mainly for backward
* compatibility.
*/
#include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/disable_warnings.h>
#include <CGAL/Arr_enums.h>
/*! \file
* Definition of the Arr_observer<Arrangement> base class.
*/
namespace CGAL {
/*! \class
* A base class for arrangement observers.
* The Arrangement parameter corresponds to an arrangement instantiation.
*/
template <typename Arrangement_>
class Arr_observer
{
public:
typedef Arrangement_ Arrangement_2;
typedef Arr_observer<Arrangement_2> Self;
typedef typename Arrangement_2::Point_2 Point_2;
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
private:
Arrangement_2* p_arr; // The associated arrangement.
/*! Copy constructor - not supported. */
Arr_observer(const Self&);
/*! Assignment operator - not supported. */
Self& operator=(const Self&);
public:
/// \name Construction and destruction functions.
//@{
/*! Default constructor. */
Arr_observer() : p_arr(nullptr) {}
/*! Constructor with an associated arrangement. */
Arr_observer(Arrangement_2& arr) : p_arr(&arr)
{
// Register the observer object in the arrangement.
p_arr->_register_observer(this);
}
/*! Destructor. */
virtual ~Arr_observer()
{
// Unregister the observer object from the arrangement.
if (p_arr != nullptr)
p_arr->_unregister_observer(this);
}
//@}
/// \name Modifying the associated arrangement.
//@{
/*! Get the associated arrangement (non-const version). */
const Arrangement_2* arrangement() const { return (p_arr); }
/*! Get the associated arrangement (non-const version). */
Arrangement_2* arrangement() { return (p_arr); }
/*! Attach the observer to an arrangement.
* \pre The observer is not already attached to an arrangement.
*/
void attach(Arrangement_2& arr)
{
// Do nothing if the associated arrangement is not changed.
if (p_arr == &arr) return;
// The observer is not already attached to an arrangement.
CGAL_precondition (p_arr == nullptr);
if (p_arr != nullptr) return;
// Notify the concrete observer (the sub-class) about the attachment.
before_attach(arr);
// Register the observer object in the new arrangement.
p_arr = &arr;
p_arr->_register_observer(this);
// Notify the concrete observer that the attachment took place.
after_attach();
}
/*! Detach the observer from the arrangement. */
void detach()
{
if (p_arr == nullptr) return;
// Notify the concrete observer (the sub-class) about the detachment.
before_detach ();
// Unregister the observer object from the current arrangement, and mark
// that the observer is not attached to an arrangement.
p_arr->_unregister_observer(this);
p_arr = nullptr;
// Notify the concrete observer that the detachment took place.
after_detach();
}
//@}
/// \name Notification functions on global arrangement operations.
//@{
/*! Notification before the arrangement is assigned with another
* arrangement.
* \param arr The arrangement to be copied.
*/
virtual void before_assign(const Arrangement_2& /* arr */) {}
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign() {}
/*! Notification before the arrangement is cleared. */
virtual void before_clear() {}
/*! Notification after the arrangement is cleared. */
virtual void after_clear() {}
/*! Notification before a global operation modifies the arrangement. */
virtual void before_global_change() {}
/*! Notification after a global operation is completed. */
virtual void after_global_change() {}
//@}
/// \name Notification functions on observer attachment or detachment.
//@{
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement we are about to attach the observer to.
*/
virtual void before_attach(const Arrangement_2& /* arr */) {}
/*! Notification after the observer has been attached to an arrangement. */
virtual void after_attach() {}
/*! Notification before the observer is detached from the arrangement. */
virtual void before_detach() {}
/*! Notification after the observer has been detached to the arrangement. */
virtual void after_detach() {}
//@}
/// \name Notification functions on local changes in the arrangement.
//@{
/*!
* Notification before the creation of a new vertex.
* \param p The point to be associated with the vertex.
* This point cannot lies on the surface boundaries.
*/
virtual void before_create_vertex(const Point_2& /* p */) {}
/*! Notification after the creation of a new vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_vertex(Vertex_handle /* v */)
{}
/*! Notification before the creation of a new boundary vertex.
* \param p The on the surface boundary.
* \param ps_x The boundary condition of the vertex in x.
* \param ps_y The boundary condition of the vertex in y.
*/
virtual void before_create_boundary_vertex(const Point_2& /* p */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{}
/*! Notification before the creation of a new boundary vertex.
* \param cv The curve incident to the surface boundary.
* \param ind The relevant curve-end.
* \param ps_x The boundary condition of the vertex in x.
* \param ps_y The boundary condition of the vertex in y.
*/
virtual void before_create_boundary_vertex(const X_monotone_curve_2& /* cv */,
Arr_curve_end /* ind */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{}
/*! Notification after the creation of a new vertex at infinity.
* \param v A handle to the created vertex.
*/
virtual void after_create_boundary_vertex(Vertex_handle /* v */) {}
/*! Notification before the creation of a new edge.
* \param c The x-monotone curve to be associated with the edge.
* \param v1 A handle to the first end-vertex of the edge.
* \param v2 A handle to the second end-vertex of the edge.
*/
virtual void before_create_edge(const X_monotone_curve_2& /* c */,
Vertex_handle /* v1 */,
Vertex_handle /* v2 */)
{}
/*! Notification after the creation of a new edge.
* \param e A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge(Halfedge_handle /* e */) {}
/*! Notification before the modification of an existing vertex.
* \param v A handle to the vertex to be updated.
* \param p The point to be associated with the vertex.
*/
virtual void before_modify_vertex(Vertex_handle /* v */,
const Point_2& /* p */)
{}
/*! Notification after a vertex was modified.
* \param v A handle to the updated vertex.
*/
virtual void after_modify_vertex(Vertex_handle /* v */) {}
/*! Notification before the modification of an existing edge.
* \param e A handle to one of the twin halfedges to be updated.
* \param c The x-monotone curve to be associated with the edge.
*/
virtual void before_modify_edge(Halfedge_handle /* e */,
const X_monotone_curve_2& /* c */)
{}
/*! Notification after an edge was modified.
* \param e A handle to one of the twin halfedges that were updated.
*/
virtual void after_modify_edge(Halfedge_handle /* e */) {}
/*! Notification before the splitting of an edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the split point.
* \param c1 The x-monotone curve to be associated with the first edge.
* \param c2 The x-monotone curve to be associated with the second edge.
*/
virtual void before_split_edge(Halfedge_handle /* e */,
Vertex_handle /* v */,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */)
{}
/*! Notification after an edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification before the splitting of a fictitious edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the unbounded split point.
*/
virtual void before_split_fictitious_edge(Halfedge_handle /* e */,
Vertex_handle /* v */)
{}
/*! Notification after a fictitious edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification before the splitting of a face into two.
* \param f A handle to the existing face.
* \param e The new edge whose insertion causes the face to split.
*/
virtual void before_split_face(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after a face was split.
* \param f A handle to the face we have just split.
* \param new_f A handle to the new face that has been created.
* \param is_hole Whether the new face forms a hole inside f.
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{}
/*! Notification before the splitting of an outer CCB into two.
* \param f A handle to the face that owns the outer CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the outer CCB to split.
*/
virtual void before_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was split.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{}
/*! Notification before the splitting of an inner CCB into two.
* \param f A handle to the face containing the inner CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the inner CCB to split.
*/
virtual void before_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was split.
* \param f A handle to the face containing the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{}
/*! Notification before the creation of a new outer CCB of a face.
* \param f A handle to the face that owns the outer CCB.
* \param e A halfedge along the new outer CCB.
*/
virtual void before_add_outer_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was added to a face.
* \param h A circulator representing the boundary of the new outer CCB.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before the creation of a new inner CCB inside a face.
* \param f A handle to the face containing the inner CCB.
* \param e The new halfedge that forms the new inner CCB.
*/
virtual void before_add_inner_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was created inside a face.
* \param h A circulator representing the boundary of the new inner CCB.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before the creation of a new isolated vertex inside a face.
* \param f A handle to the face containing the isolated vertex.
* \param v The isolated vertex.
*/
virtual void before_add_isolated_vertex(Face_handle /* f */,
Vertex_handle /* v */)
{}
/*! Notification after an isolated vertex was created inside a face.
* \param v The isolated vertex.
*/
virtual void after_add_isolated_vertex(Vertex_handle /* v */) {}
/*! Notification before the merging of two edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
* \param c The x-monotone curve to be associated with the merged edge.
*/
virtual void before_merge_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */,
const X_monotone_curve_2& /* c */)
{}
/*! Notification after an edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge(Halfedge_handle /* e */) {}
/*! Notification before the merging of two fictitious edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
*/
virtual void before_merge_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{}
/*! Notification after a fictitious edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_fictitious_edge(Halfedge_handle /* e */) {}
/*! Notification before the merging of two faces.
* \param f1 A handle to the first face.
* \param f2 A handle to the second face.
* \param e The edge whose removal causes the faces to merge.
*/
virtual void before_merge_face(Face_handle /* f1 */,
Face_handle /* f2 */,
Halfedge_handle /* e */)
{}
/*! Notification after a face was merged.
* \param f A handle to the merged face.
*/
virtual void after_merge_face(Face_handle /* f */) {}
/*! Notification before the merging of two outer CCBs.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
* \param e The edge whose insertion or removal causes the CCBs to merge.
*/
virtual void before_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{}
/*! Notification after an outer CCB was merged.
* \param f A handle to the face that owns the outer CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification before the merging of two inner CCBs (holes).
* \param f A handle to the face that contains the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
* \param e The edge whose insertion causes the inner CCBs to merge.
*/
virtual void before_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{}
/*! Notification after an inner CCB was merged.
* \param f A handle to the face that contains the inner CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification before an outer CCB is moved from one face to another.
* \param from_f A handle to the face that currently owns the outer CCB.
* \param to_f A handle to the face that should own the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_outer_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notification after an outer CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before an inner CCB is moved from one face to another.
* \param from_f A handle to the face currently containing the inner CCB.
* \param to_f A handle to the face that should contain the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_inner_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{}
/*!
* Notification after an inner CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */) {}
/*! Notification before an isolated vertex is moved from one face to another.
* \param from_f A handle to the face currently containing the vertex.
* \param to_f A handle to the face that should contain the vertex.
* \param v The isolated vertex.
*/
virtual void before_move_isolated_vertex(Face_handle /* from_f */,
Face_handle /* to_f */,
Vertex_handle /* v */)
{}
/*! Notification after an isolated vertex is moved from one face to another.
* \param v The isolated vertex.
*/
virtual void after_move_isolated_vertex(Vertex_handle /* v */) {}
/*! Notificaion before the removal of a vertex.
* \param v A handle to the vertex to be deleted.
*/
virtual void before_remove_vertex(Vertex_handle /* v */) {}
/*! Notificaion after the removal of a vertex. */
virtual void after_remove_vertex() {}
/*! Notification before the removal of an edge.
* \param e A handle to one of the twin halfedges to be deleted.
*/
virtual void before_remove_edge(Halfedge_handle /* e */) {}
/*! Notificaion after the removal of an edge. */
virtual void after_remove_edge() {}
/*! Notification before the removal of an outer CCB.
* \param f The face that owns the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notificaion after the removal of an outer CCB.
* \param f The face that used to own the outer CCB.
*/
virtual void after_remove_outer_ccb(Face_handle /* f */) {}
/*! Notification before the removal of an inner CCB.
* \param f The face containing the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{}
/*! Notificaion after the removal of an inner CCB.
* \param f The face that used to contain the inner CCB.
*/
virtual void after_remove_inner_ccb(Face_handle /* f */) {}
//@}
};
using Arr_observer = typename Arrangement_::Observer;
} // namespace CGAL

View File

@ -20,7 +20,6 @@
* Definition of the Arr_landmarks_generator_base<Arrangement> template.
*/
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location/Arr_lm_nearest_neighbor.h>
#include <CGAL/Arr_batched_point_location.h>
@ -44,43 +43,43 @@ namespace CGAL {
template <typename Arrangement_,
typename Nearest_neighbor_ =
Arr_landmarks_nearest_neighbor<Arrangement_> >
class Arr_landmarks_generator_base : public Arr_observer <Arrangement_> {
class Arr_landmarks_generator_base : public Arrangement_::Observer {
public:
typedef Arrangement_ Arrangement_2;
typedef Nearest_neighbor_ Nearest_neighbor;
using Arrangement_2 = Arrangement_;
using Base_aos = typename Arrangement_2::Base_aos;
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
using Nearest_neighbor = Nearest_neighbor_;
typedef typename Arrangement_2::Point_2 Point_2;
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
using Geometry_traits_2 = typename Base_aos::Geometry_traits_2;
using Vertex_const_handle = typename Base_aos::Vertex_const_handle;
using Halfedge_const_handle = typename Base_aos::Halfedge_const_handle;
using Face_const_handle = typename Base_aos::Face_const_handle;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using Face_handle = typename Base_aos::Face_handle;
using Vertex_const_iterator = typename Base_aos::Vertex_const_iterator;
using Ccb_halfedge_circulator = typename Base_aos::Ccb_halfedge_circulator;
typedef typename Nearest_neighbor::NN_Point_2 NN_Point_2;
typedef std::list<NN_Point_2> NN_Points_set;
using Point_2 = typename Base_aos::Point_2;
using X_monotone_curve_2 = typename Base_aos::X_monotone_curve_2;
typedef std::vector<Point_2> Points_set;
using NN_Point_2 = typename Nearest_neighbor::NN_Point_2;
using NN_Points_set = std::list<NN_Point_2>;
typedef Arr_point_location_result<Arrangement_2> PL_result;
typedef typename PL_result::Type PL_result_type;
using Points_set = std::vector<Point_2>;
typedef std::pair<Point_2, PL_result_type> PL_pair;
typedef std::vector<PL_pair> Pairs_set;
typedef typename std::vector<PL_pair>::iterator Pairs_iterator;
using PL_result = Arr_point_location_result<Base_aos>;
using PL_result_type = typename PL_result::Type;
using PL_pair = std::pair<Point_2, PL_result_type>;
using Pairs_set = std::vector<PL_pair>;
using Pairs_iterator = typename std::vector<PL_pair>::iterator;
private:
typedef Arr_landmarks_generator_base<Arrangement_2, Nearest_neighbor>
Self;
using Self = Arr_landmarks_generator_base<Arrangement_2, Nearest_neighbor>;
protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
using Traits_adaptor_2 = Arr_traits_basic_adaptor_2<Geometry_traits_2>;
// Data members:
const Traits_adaptor_2* m_traits; // The associated traits object.
@ -109,8 +108,8 @@ public:
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_landmarks_generator_base(const Arrangement_2& arr) :
Arr_observer<Arrangement_2> (const_cast<Arrangement_2 &>(arr)),
Arr_landmarks_generator_base(const Base_aos& arr) :
Base_aos::Observer(const_cast<Base_aos&>(arr)),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
m_ignore_notifications(false),
m_ignore_remove_edge(false),
@ -124,8 +123,7 @@ public:
/*! Create the landmarks set (choosing the landmarks) ,
* and saving them in the nearest-neighbor search structure.
*/
virtual void build_landmark_set()
{
virtual void build_landmark_set() {
// Create the landmark points.
NN_Points_set nn_points;
_create_nn_points_set(nn_points);
@ -140,8 +138,7 @@ public:
/*! clear the set of landmarks.
*/
virtual void clear_landmark_set()
{
virtual void clear_landmark_set() {
nn.clear();
num_small_not_updated_changes = 0;
updated = false;
@ -153,8 +150,7 @@ public:
* arrangement (a vertex, halfedge, or face handle).
* \return The nearest landmark point.
*/
virtual Point_2 closest_landmark(const Point_2& p, PL_result_type& obj)
{
virtual Point_2 closest_landmark(const Point_2& p, PL_result_type& obj) {
CGAL_assertion(updated);
return (nn.find_nearest_neighbor(p, obj));
}
@ -162,13 +158,13 @@ public:
/// \name Overloaded observer functions on global changes.
//@{
/*!
* Notification before the arrangement is assigned with another
* arrangement.
* \param arr The arrangement to be copied.
/*! Notification before the arrangement is assigned with the content of
* another arrangement.
* \param arr The other arrangement. Notice that the arrangement type is the
* type used to instantiate the observer, which is conveniently
* defined as `Arrangement_2::Base_aos`.
*/
virtual void before_assign(const Arrangement_2& arr)
{
virtual void before_assign(const Base_aos& arr) override {
this->clear_landmark_set();
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
m_ignore_notifications = true;
@ -177,8 +173,7 @@ public:
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign()
{
virtual void after_assign() override {
this->build_landmark_set();
m_ignore_notifications = false;
}
@ -186,8 +181,7 @@ public:
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement we are about to attach the observer to.
*/
virtual void before_attach(const Arrangement_2& arr)
{
virtual void before_attach(const Base_aos& arr) override {
this->clear_landmark_set();
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
m_ignore_notifications = true;
@ -195,38 +189,33 @@ public:
/*! Notification after the observer has been attached to an arrangement.
*/
virtual void after_attach()
{
virtual void after_attach() override {
this->build_landmark_set();
m_ignore_notifications = false;
}
/*! Notification before the observer is detached from the arrangement.
*/
virtual void before_detach()
{ this->clear_landmark_set(); }
virtual void before_detach() override { this->clear_landmark_set(); }
/*! Notification after the arrangement is cleared.
* \param u A handle to the unbounded face.
*/
virtual void after_clear()
{
virtual void after_clear() override {
this->clear_landmark_set();
this->build_landmark_set();
}
/*! Notification before a global operation modifies the arrangement.
*/
virtual void before_global_change()
{
virtual void before_global_change() override {
this->clear_landmark_set();
m_ignore_notifications = true;
}
/*! Notification after a global operation is completed.
*/
virtual void after_global_change()
{
virtual void after_global_change() override {
this->build_landmark_set();
m_ignore_notifications = false;
}
@ -238,12 +227,11 @@ public:
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be removed.
*/
virtual void before_remove_edge(Halfedge_handle /* e */)
virtual void before_remove_edge(Halfedge_handle /* e */) override
{ m_ignore_remove_edge = true; }
/*! Notification after the creation of a new vertex. */
virtual void after_create_vertex(Vertex_handle)
{
virtual void after_create_vertex(Vertex_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -251,8 +239,7 @@ public:
}
/*! Notification after the creation of a new edge. */
virtual void after_create_edge(Halfedge_handle)
{
virtual void after_create_edge(Halfedge_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -260,8 +247,7 @@ public:
}
/*! Notification after an edge was split. */
virtual void after_split_edge(Halfedge_handle, Halfedge_handle)
{
virtual void after_split_edge(Halfedge_handle, Halfedge_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -269,8 +255,7 @@ public:
}
/*! Notification after a face was split. */
virtual void after_split_face(Face_handle, Face_handle, bool)
{
virtual void after_split_face(Face_handle, Face_handle, bool) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -280,8 +265,7 @@ public:
/*! Notification after an outer CCB was split.*/
virtual void after_split_outer_ccb(Face_handle,
Ccb_halfedge_circulator,
Ccb_halfedge_circulator)
{
Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -291,8 +275,7 @@ public:
/*! Notification after an inner CCB was split. */
virtual void after_split_inner_ccb(Face_handle,
Ccb_halfedge_circulator,
Ccb_halfedge_circulator)
{
Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -300,8 +283,7 @@ public:
}
/*! Notification after an outer CCB was added to a face. */
virtual void after_add_outer_ccb(Ccb_halfedge_circulator)
{
virtual void after_add_outer_ccb(Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -309,8 +291,7 @@ public:
}
/*! Notification after an inner CCB was created inside a face. */
virtual void after_add_inner_ccb(Ccb_halfedge_circulator)
{
virtual void after_add_inner_ccb(Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -318,8 +299,7 @@ public:
}
/*! Notification after an isolated vertex was created inside a face. */
virtual void after_add_isolated_vertex(Vertex_handle)
{
virtual void after_add_isolated_vertex(Vertex_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -327,8 +307,7 @@ public:
}
/*! Notification after an edge was merged. */
virtual void after_merge_edge(Halfedge_handle)
{
virtual void after_merge_edge(Halfedge_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -336,8 +315,7 @@ public:
}
/*! Notification after a face was merged. */
virtual void after_merge_face(Face_handle)
{
virtual void after_merge_face(Face_handle) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
@ -346,7 +324,7 @@ public:
/*! Notification after an outer CCB was merged. */
virtual void after_merge_outer_ccb(Face_handle, Ccb_halfedge_circulator)
{
override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -355,7 +333,7 @@ public:
/*! Notification after an inner CCB was merged. */
virtual void after_merge_inner_ccb(Face_handle, Ccb_halfedge_circulator)
{
override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -363,8 +341,7 @@ public:
}
/*! Notification after an outer CCB is moved from one face to another. */
virtual void after_move_outer_ccb(Ccb_halfedge_circulator )
{
virtual void after_move_outer_ccb(Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -372,8 +349,7 @@ public:
}
/*! Notification after an inner CCB is moved from one face to another. */
virtual void after_move_inner_ccb(Ccb_halfedge_circulator )
{
virtual void after_move_inner_ccb(Ccb_halfedge_circulator) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -381,8 +357,7 @@ public:
}
/*! Notification after an isolated vertex is moved. */
virtual void after_move_isolated_vertex(Vertex_handle )
{
virtual void after_move_isolated_vertex(Vertex_handle) override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -390,8 +365,7 @@ public:
}
/*! Notificaion after the removal of a vertex. */
virtual void after_remove_vertex()
{
virtual void after_remove_vertex() override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
@ -399,8 +373,7 @@ public:
}
/*! Notification after the removal of an edge. */
virtual void after_remove_edge()
{
virtual void after_remove_edge() override {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
@ -409,8 +382,7 @@ public:
}
/*! Notificaion after the removal of an outer CCB. */
virtual void after_remove_outer_ccb(Face_handle)
{
virtual void after_remove_outer_ccb(Face_handle) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
@ -418,8 +390,7 @@ public:
}
/*! Notificaion after the removal of an inner CCB. */
virtual void after_remove_inner_ccb(Face_handle)
{
virtual void after_remove_inner_ccb(Face_handle) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
@ -434,8 +405,7 @@ protected:
*/
virtual void _create_points_set(Points_set&) = 0;
virtual void _create_nn_points_set(NN_Points_set& nn_points)
{
virtual void _create_nn_points_set(NN_Points_set& nn_points) {
Points_set points;
Pairs_set pairs;
@ -453,8 +423,7 @@ protected:
// Insert all landmarks (paired with their current location in the
// arrangement) into the nearest-neighbor search structure.
Pairs_iterator itr;
for (itr = pairs.begin(); itr != pairs.end(); ++itr) {
for (auto itr = pairs.begin(); itr != pairs.end(); ++itr) {
NN_Point_2 np(itr->first, itr->second);
nn_points.push_back(np);
}

View File

@ -99,13 +99,12 @@ public:
{
// Go over the arrangement, and insert all its vertices as landmarks.
NN_Point_list nnp_list;
const Arrangement_2* arr = this->arrangement();
Vertex_const_iterator vit;
const auto* arr = this->arrangement();
num_landmarks = 0;
for (vit = arr->vertices_begin(); vit != arr->vertices_end(); ++vit) {
for (auto vit = arr->vertices_begin(); vit != arr->vertices_end(); ++vit) {
Vertex_const_handle vh = vit;
nnp_list.push_back(NN_Point_2(vh->point(), this->pl_make_result(vh)));
num_landmarks++;
++num_landmarks;
}
// Update the search structure.

View File

@ -177,6 +177,7 @@ public:
//typedef of arrangement on surface
typedef typename Traits::Arrangement_on_surface_2 Arrangement_on_surface_2;
using Base_aos = typename Arrangement_on_surface_2::Base_aos;
//type of traits adaptor
typedef typename Traits::Arrangement_on_surface_2::Traits_adaptor_2
@ -1804,7 +1805,7 @@ public:
return m_number_of_curves;
}
void init_arrangement_and_traits(const Arrangement_on_surface_2* arr,
void init_arrangement_and_traits(const Base_aos* arr,
bool allocate_traits = true)
{
m_arr = arr;
@ -2125,7 +2126,7 @@ protected:
unsigned long m_number_of_curves;
const Traits* traits;
//Before_split_data m_before_split;
const Arrangement_on_surface_2* m_arr;
const Base_aos* m_arr;
const Traits_adaptor_2* m_trts_adaptor;
Halfedge_const_handle m_empty_he_handle;

View File

@ -26,7 +26,6 @@
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location/Trapezoidal_decomposition_2.h>
#include <CGAL/Arr_point_location/Td_traits.h>
#include <CGAL/Arr_observer.h>
namespace CGAL {
@ -36,86 +35,85 @@ namespace CGAL {
* The Arrangement parameter corresponds to an arrangement instantiation.
*/
template <typename Arrangement_>
class Arr_trapezoid_ric_point_location : public Arr_observer <Arrangement_> {
class Arr_trapezoid_ric_point_location : public Arrangement_::Observer {
public:
//type of arrangement on surface
typedef Arrangement_ Arrangement_on_surface_2;
using Arrangement_on_surface_2 = Arrangement_;
using Base_aos = typename Arrangement_on_surface_2::Base_aos;
//type of geometry traits
typedef typename Arrangement_on_surface_2::Geometry_traits_2
Geometry_traits_2;
using Geometry_traits_2 = typename Base_aos::Geometry_traits_2;
//type of traits adaptor
typedef typename Arrangement_on_surface_2::Traits_adaptor_2
Traits_adaptor_2;
using Traits_adaptor_2 = typename Base_aos::Traits_adaptor_2;
//type of vertex handle
typedef typename Arrangement_on_surface_2::Vertex_handle
Vertex_handle;
using Vertex_handle = typename Base_aos::Vertex_handle;
//type of vertex const handle
typedef typename Arrangement_on_surface_2::Vertex_const_handle
Vertex_const_handle;
using Vertex_const_handle = typename Base_aos::Vertex_const_handle;
//type of halfedge handle
typedef typename Arrangement_on_surface_2::Halfedge_handle
Halfedge_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
//type of halfedge const handle
typedef typename Arrangement_on_surface_2::Halfedge_const_handle
Halfedge_const_handle;
using Halfedge_const_handle = typename Base_aos::Halfedge_const_handle;
//type of face const handle
typedef typename Arrangement_on_surface_2::Face_const_handle
Face_const_handle;
using Face_const_handle = typename Base_aos::Face_const_handle;
//type of edge const iterator
typedef typename Arrangement_on_surface_2::Edge_const_iterator
Edge_const_iterator;
using Edge_const_iterator = typename Base_aos::Edge_const_iterator;
//type of isolated vertex const iterator
typedef typename Arrangement_on_surface_2::Isolated_vertex_const_iterator
Isolated_vertex_const_iterator;
using Isolated_vertex_const_iterator =
typename Base_aos::Isolated_vertex_const_iterator;
//type of point
typedef typename Geometry_traits_2::Point_2 Point_2;
using Point_2 = typename Geometry_traits_2::Point_2;
//type of x-monotone curve
typedef typename Geometry_traits_2::X_monotone_curve_2
X_monotone_curve_2;
using X_monotone_curve_2 = typename Geometry_traits_2::X_monotone_curve_2;
//type of trapezoidal decomposition traits class
typedef CGAL::Td_traits<Traits_adaptor_2, Arrangement_on_surface_2>
Td_traits;
using Td_traits = CGAL::Td_traits<Traits_adaptor_2, Base_aos>;
//type of trapezoidal decomposition class
typedef Trapezoidal_decomposition_2<Td_traits>
Trapezoidal_decomposition;
using Trapezoidal_decomposition = Trapezoidal_decomposition_2<Td_traits>;
//!types of Td_map_item-s
typedef typename Trapezoidal_decomposition::Td_map_item
Td_map_item;
typedef typename Trapezoidal_decomposition::Td_active_vertex
Td_active_vertex;
typedef typename Trapezoidal_decomposition::Td_active_fictitious_vertex
Td_active_fictitious_vertex;
typedef typename Trapezoidal_decomposition::Td_active_edge
Td_active_edge;
typedef typename Trapezoidal_decomposition::Td_active_trapezoid
Td_active_trapezoid;
using Td_map_item = typename Trapezoidal_decomposition::Td_map_item;
using Td_active_vertex = typename Trapezoidal_decomposition::Td_active_vertex;
using Td_active_fictitious_vertex =
typename Trapezoidal_decomposition::Td_active_fictitious_vertex;
using Td_active_edge = typename Trapezoidal_decomposition::Td_active_edge;
using Td_active_trapezoid =
typename Trapezoidal_decomposition::Td_active_trapezoid;
//!type of side tags
typedef typename Traits_adaptor_2::Left_side_category Left_side_category;
typedef typename Traits_adaptor_2::Bottom_side_category Bottom_side_category;
typedef typename Traits_adaptor_2::Top_side_category Top_side_category;
typedef typename Traits_adaptor_2::Right_side_category Right_side_category;
using Left_side_category = typename Traits_adaptor_2::Left_side_category;
using Bottom_side_category = typename Traits_adaptor_2::Bottom_side_category;
using Top_side_category = typename Traits_adaptor_2::Top_side_category;
using Right_side_category = typename Traits_adaptor_2::Right_side_category;
protected:
typedef Arr_point_location_result<Arrangement_on_surface_2> Result;
typedef typename Result::Type Result_type;
using Result = Arr_point_location_result<Base_aos>;
using Result_type = typename Result::Type;
public:
// Support cpp11::result_of
typedef Result_type result_type;
using result_type = Result_type;
protected:
//type of trapezoidal decomposition class
typedef Trapezoidal_decomposition TD;
using TD = Trapezoidal_decomposition;
typedef typename Arr_all_sides_oblivious_category<Left_side_category,
using All_sides_oblivious_category=
typename Arr_all_sides_oblivious_category<Left_side_category,
Bottom_side_category,
Top_side_category,
Right_side_category>::result
All_sides_oblivious_category;
Right_side_category>::result;
// Data members:
const Traits_adaptor_2* m_traits; // Its associated traits object.
@ -133,25 +131,24 @@ protected:
public:
/*! Default constructor. */
Arr_trapezoid_ric_point_location(bool with_guarantees = true,
Arr_trapezoid_ric_point_location
(bool with_guarantees = true,
double depth_thrs = CGAL_TD_DEFAULT_DEPTH_THRESHOLD,
double size_thrs = CGAL_TD_DEFAULT_SIZE_THRESHOLD) :
m_traits(nullptr), m_with_guarantees(with_guarantees)
{
m_traits(nullptr), m_with_guarantees(with_guarantees) {
td.set_with_guarantees(with_guarantees);
td.depth_threshold(depth_thrs);
td.size_threshold(size_thrs);
}
/*! Constructor given an arrangement. */
Arr_trapezoid_ric_point_location (const Arrangement_on_surface_2& arr,
Arr_trapezoid_ric_point_location
(const Base_aos& arr,
bool with_guarantees = true,
double depth_thrs = CGAL_TD_DEFAULT_DEPTH_THRESHOLD,
double size_thrs = CGAL_TD_DEFAULT_SIZE_THRESHOLD) :
Arr_observer<Arrangement_on_surface_2>
(const_cast<Arrangement_on_surface_2 &>(arr)),
m_with_guarantees(with_guarantees)
{
Base_aos::Observer(const_cast<Base_aos&>(arr)),
m_with_guarantees(with_guarantees) {
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
td.set_with_guarantees(with_guarantees);
td.init_arrangement_and_traits(&arr);
@ -165,13 +162,11 @@ public:
/*! defines whether the underlying search structure guarantees logarithmic
* query time and linear size */
void with_guarantees (bool with_guarantees)
{
void with_guarantees(bool with_guarantees) {
//if with_guarantees was changed from false to true - reconstruct
// the search structure with guarantees
td.set_with_guarantees(with_guarantees);
if (with_guarantees && !m_with_guarantees)
{
if (with_guarantees && !m_with_guarantees) {
td.clear();
_construct_td();
}
@ -182,30 +177,20 @@ public:
* (the longest path in the DAG)
*/
unsigned long depth() //longest_dag_path()
{
return td.largest_leaf_depth() + 1;
}
{ return td.largest_leaf_depth() + 1; }
/*! returns the longest query path in the underlying search structure */
unsigned long longest_query_path_length()
{
return td.longest_query_path_length();
}
{ return td.longest_query_path_length(); }
#ifdef CGAL_TD_DEBUG
//void locate_and_print (std::ostream& out, const Point_2& p) const
//{
// td.locate_and_print(out, p);
//}
//{ td.locate_and_print(out, p); }
void print_dag(std::ostream& out) const
{
td.print_dag(out);
}
void print_dag(std::ostream& out) const { td.print_dag(out); }
#endif
/*!
* Locate the arrangement feature containing the given point.
/*! Locate the arrangement feature containing the given point.
* \param p The query point.
* \return An object representing the arrangement feature containing the
* query point. This object is either a Face_const_handle or a
@ -213,8 +198,7 @@ public:
*/
result_type locate(const Point_2& p) const;
/*!
* Locate the arrangement feature which a upward vertical ray emanating from
/*! Locate the arrangement feature which a upward vertical ray emanating from
* the given point hits.
* \param p The query point.
* \return An object representing the arrangement feature the ray hits.
@ -224,8 +208,7 @@ public:
result_type ray_shoot_up(const Point_2& p) const
{ return (_vertical_ray_shoot(p, true)); }
/*!
* Locate the arrangement feature which a downward vertical ray emanating
/*! Locate the arrangement feature which a downward vertical ray emanating
* from the given point hits.
* \param p The query point.
* \return An object representing the arrangement feature the ray hits.
@ -239,49 +222,41 @@ public:
// base observer.
//@{
virtual void before_assign (const Arrangement_on_surface_2& arr)
{
/*! Notification before the arrangement is assigned with the content of
* another arrangement.
* \param arr The other arrangement. Notice that the arrangement type is the
* type used to instantiate the observer, which is conveniently
* defined as `Arrangement_2::Base_aos`.
*/
virtual void before_assign(const Base_aos& arr) override {
td.clear();
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
td.init_arrangement_and_traits(&arr, false);
}
virtual void after_assign ()
{
_construct_td();
}
virtual void after_assign() override { _construct_td(); }
virtual void before_clear ()
{
td.clear();
}
virtual void before_clear() override { td.clear(); }
virtual void after_clear ()
{
_construct_td();
}
virtual void after_clear() override { _construct_td(); }
virtual void before_attach (const Arrangement_on_surface_2& arr)
{
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement that is about to attach the observer. Notice
* that the arrangement type is the type used to instantiate the
* observer, which is conveniently defined as
* `Arrangement_2::Base_aos`.
*/
virtual void before_attach(const Base_aos& arr) override {
td.clear();
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
td.init_arrangement_and_traits(&arr);
}
virtual void after_attach ()
{
_construct_td();
}
virtual void after_attach() override { _construct_td(); }
virtual void before_detach ()
{
td.clear();
}
virtual void before_detach() override { td.clear(); }
virtual void after_create_edge (Halfedge_handle e)
{
td.insert(e);
}
virtual void after_create_edge(Halfedge_handle e) override { td.insert(e); }
//TODO IDIT OREN: what can be done in order to avoid the need
//to save the original curve is to find the common endpoint of the
@ -291,20 +266,18 @@ public:
virtual void before_split_edge(Halfedge_handle e,
Vertex_handle /* v */,
const X_monotone_curve_2& /* cv1 */,
const X_monotone_curve_2& /* cv2 */ )
{
const X_monotone_curve_2& /* cv2 */) override {
////MICHAL: commented due to inefficient depth update, remove and insert instead
////save the curve for the "after" function.
////MICHAL: commented due to inefficient depth update, remove and insert
////instead save the curve for the "after" function.
//m_cv_before_split = e->curve();
//td.before_split_edge(m_cv_before_split, cv1, cv2);
td.remove(e);
}
virtual void after_split_edge (Halfedge_handle e1,
Halfedge_handle e2)
{
virtual void after_split_edge(Halfedge_handle e1, Halfedge_handle e2)
override {
//MICHAL: commented due to inefficient depth update, remove and insert instead
//td.split_edge(m_cv_before_split,e1,e2);
@ -312,29 +285,20 @@ public:
td.insert(e2);
}
virtual void before_merge_edge (Halfedge_handle e1,
Halfedge_handle e2,
const X_monotone_curve_2& cv)
{
virtual void before_merge_edge(Halfedge_handle e1, Halfedge_handle e2,
const X_monotone_curve_2& cv) override {
//save the halfedge handle for the "after" function.
m_he_after_merge = e1;
td.merge_edge (e1, e2, cv);
}
virtual void after_merge_edge (Halfedge_handle e)
{
td.after_merge_edge(e, m_he_after_merge);
}
virtual void after_merge_edge(Halfedge_handle e) override
{ td.after_merge_edge(e, m_he_after_merge); }
virtual void before_remove_edge (Halfedge_handle e)
{
//called before combinatoric deletion
td.remove(e);
}
virtual void before_remove_edge(Halfedge_handle e) override { td.remove(e); }
//@}
public:
//#ifdef CGAL_TD_DEBUG
// void debug()
// {
@ -343,27 +307,22 @@ public:
//#endif
protected:
/*! Construct the trapezoidal decomposition. */
void _construct_td ()
{
void _construct_td() {
td.clear();
std::vector<Halfedge_const_handle> he_container;
Edge_const_iterator eit;
Halfedge_const_handle he_cst;
Arrangement_on_surface_2 *arr = this->arrangement();
auto* arr = this->arrangement();
//collect the arrangement halfedges
for (eit = arr->edges_begin(); eit != arr->edges_end(); ++eit)
{
he_cst = eit;
for (auto eit = arr->edges_begin(); eit != arr->edges_end(); ++eit) {
Halfedge_const_handle he_cst = eit;
he_container.push_back(he_cst);
}
//container insertion
td.insert(he_container.begin(), he_container.end());
}
/*! gets the unbounded face that contains the point when the trapezoid is
/*! Obtain the unbounded face that contains the point when the trapezoid is
* unbounded
* \param tr The unbounded trapezoid whose face we should get
* \param p The query point.
@ -375,20 +334,19 @@ protected:
const Point_2& p,
Arr_all_sides_oblivious_tag) const;
/*! gets the unbounded face that contains the point when the trapezoid is
/*! Obtain the unbounded face that contains the point when the trapezoid is
* unbounded
* \param tr The unbounded trapezoid whose face we should get
* \param p The query point.
* \param Arr_not_all_sides_oblivious_tag
* \return A Face_const_handle representing the arrangement unbounded face in which
* the point p lies
* \return A Face_const_handle representing the arrangement unbounded face in
* which the point p lies
*/
Face_const_handle _get_unbounded_face(const Td_map_item& tr,
const Point_2& p,
Arr_not_all_sides_oblivious_tag) const;
/*!
* Locate the arrangement feature which a vertical ray emanating from the
/*! Locate the arrangement feature which a vertical ray emanating from the
* given point hits, considering isolated vertices.
* \param p The query point.
* \param shoot_up Indicates whether the ray is directed upward or downward.
@ -403,8 +361,7 @@ protected:
* we check the isolated vertices inside the face to check whether there
* is an isolated vertex right above/below the query point.
*/
result_type
_check_isolated_for_vertical_ray_shoot
result_type _check_isolated_for_vertical_ray_shoot
(Halfedge_const_handle halfedge_found,
const Point_2& p, bool shoot_up,
const Td_map_item& tr) const;

View File

@ -21,7 +21,6 @@
* Definition of the Arr_triangulation_point_location<Arrangement> template.
*/
#include <CGAL/Arr_observer.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
@ -39,73 +38,70 @@ namespace CGAL {
* triangulation algorithm.
*/
template <typename Arrangement_>
class Arr_triangulation_point_location : public Arr_observer<Arrangement_>
{
class Arr_triangulation_point_location : public Arrangement_::Observer {
public:
typedef Arrangement_ Arrangement_2;
using Arrangement_2 = Arrangement_;
using Base_aos = typename Arrangement_2::Base_aos;
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
typedef typename Geometry_traits_2::Kernel Kernel;
using Geometry_traits_2 = typename Base_aos::Geometry_traits_2;
using Kernel = typename Geometry_traits_2::Kernel;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
using Vertex_const_handle = typename Base_aos::Vertex_const_handle;
using Halfedge_const_handle = typename Base_aos::Halfedge_const_handle;
using Face_const_handle = typename Base_aos::Face_const_handle;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using Face_handle = typename Base_aos::Face_handle;
typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator;
typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement_2::Face_const_iterator Face_const_iterator;
typedef typename Arrangement_2::Halfedge_const_iterator
Halfedge_const_iterator;
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
Halfedge_around_vertex_const_circulator;
typedef typename Arrangement_2::Ccb_halfedge_const_circulator
Ccb_halfedge_const_circulator;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Arrangement_2::Isolated_vertex_const_iterator
Isolated_vertex_const_iterator;
using Vertex_const_iterator = typename Base_aos::Vertex_const_iterator;
using Edge_const_iterator = typename Base_aos::Edge_const_iterator;
using Face_const_iterator = typename Base_aos::Face_const_iterator;
using Halfedge_const_iterator = typename Base_aos::Halfedge_const_iterator;
using Halfedge_around_vertex_const_circulator =
typename Base_aos::Halfedge_around_vertex_const_circulator;
using Ccb_halfedge_const_circulator =
typename Base_aos::Ccb_halfedge_const_circulator;
using Ccb_halfedge_circulator = typename Base_aos::Ccb_halfedge_circulator;
using Isolated_vertex_const_iterator =
typename Base_aos::Isolated_vertex_const_iterator;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
using Point_2 = typename Geometry_traits_2::Point_2;
using X_monotone_curve_2 = typename Geometry_traits_2::X_monotone_curve_2;
typedef std::list<Halfedge_const_handle> Edge_list;
typedef typename Edge_list::iterator Std_edge_iterator;
using Edge_list = std::list<Halfedge_const_handle>;
using Std_edge_iterator = typename Edge_list::iterator;
//----------------------------------------------------------
// Triangulation Types
//----------------------------------------------------------
typedef Triangulation_vertex_base_with_info_2<Vertex_const_handle, Kernel>
Vbb;
typedef Triangulation_hierarchy_vertex_base_2<Vbb> Vb;
using Vbb = Triangulation_vertex_base_with_info_2<Vertex_const_handle, Kernel>;
using Vb = Triangulation_hierarchy_vertex_base_2<Vbb>;
//typedef Triangulation_face_base_with_info_2<CGAL::IO::Color,Kernel> Fbt;
typedef Constrained_triangulation_face_base_2<Kernel> Fb;
typedef Triangulation_data_structure_2<Vb,Fb> TDS;
typedef Exact_predicates_tag Itag;
using Fb = Constrained_triangulation_face_base_2<Kernel>;
using TDS = Triangulation_data_structure_2<Vb,Fb>;
using Itag = Exact_predicates_tag;
//typedef Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT;
typedef Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT_t;
typedef Triangulation_hierarchy_2<CDT_t> CDTH;
typedef Constrained_triangulation_plus_2<CDTH> CDT;
using CDT_t = Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag>;
using CDTH = Triangulation_hierarchy_2<CDT_t>;
using CDT = Constrained_triangulation_plus_2<CDTH>;
typedef typename CDT::Point CDT_Point;
typedef typename CDT::Edge CDT_Edge;
typedef typename CDT::Face_handle CDT_Face_handle;
typedef typename CDT::Vertex_handle CDT_Vertex_handle;
typedef typename CDT::Finite_faces_iterator CDT_Finite_faces_iterator;
typedef typename CDT::Finite_vertices_iterator CDT_Finite_vertices_iterator;
typedef typename CDT::Finite_edges_iterator CDT_Finite_edges_iterator;
typedef typename CDT::Locate_type CDT_Locate_type;
using CDT_Point = typename CDT::Point;
using CDT_Edge = typename CDT::Edge;
using CDT_Face_handle = typename CDT::Face_handle;
using CDT_Vertex_handle = typename CDT::Vertex_handle;
using CDT_Finite_faces_iterator = typename CDT::Finite_faces_iterator;
using CDT_Finite_vertices_iterator = typename CDT::Finite_vertices_iterator;
using CDT_Finite_edges_iterator = typename CDT::Finite_edges_iterator;
using CDT_Locate_type = typename CDT::Locate_type;
typedef Arr_point_location_result<Arrangement_2> Result;
typedef typename Result::Type Result_type;
using Result = Arr_point_location_result<Base_aos>;
using Result_type = typename Result::Type;
// Support cpp11::result_of
typedef Result_type result_type;
using result_type = Result_type;
protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
using Traits_adaptor_2 = Arr_traits_basic_adaptor_2<Geometry_traits_2>;
// Data members:
const Traits_adaptor_2* m_traits; // Its associated traits object.
@ -128,8 +124,8 @@ public:
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_triangulation_point_location(const Arrangement_2& arr) :
Arr_observer<Arrangement_2>(const_cast<Arrangement_2&>(arr)),
Arr_triangulation_point_location(const Base_aos& arr) :
Base_aos::Observer(const_cast<Base_aos&>(arr)),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
m_ignore_notifications(false),
m_ignore_remove_edge(false)
@ -149,12 +145,12 @@ public:
/*! Attach an arrangement.
* \param arr (in) The arrangement.
*/
virtual void before_attach(const Arrangement_2& arr)
virtual void before_attach(const Base_aos& arr) override
{ m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits()); }
virtual void after_attach() { build_triangulation(); }
virtual void after_attach() override { build_triangulation(); }
virtual void before_detach() { clear_triangulation(); }
virtual void before_detach() override { clear_triangulation(); }
/// \name Overloaded observer functions on global changes.
//@{
@ -162,32 +158,28 @@ public:
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign()
{
virtual void after_assign() override {
clear_triangulation();
build_triangulation();
}
/*! Notification after the arrangement is cleared.
*/
virtual void after_clear()
{
virtual void after_clear() override {
clear_triangulation();
build_triangulation();
}
/*! Notification before a global operation modifies the arrangement.
*/
virtual void before_global_change()
{
virtual void before_global_change() override {
clear_triangulation();
m_ignore_notifications = true;
}
/*! Notification after a global operation is completed.
*/
virtual void after_global_change()
{
virtual void after_global_change() override {
build_triangulation();
m_ignore_notifications = false;
}
@ -199,14 +191,13 @@ public:
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be removed.
*/
virtual void before_remove_edge(Halfedge_handle /* e */)
virtual void before_remove_edge(Halfedge_handle /* e */) override
{ m_ignore_remove_edge = true; }
/*! Notification after the creation of a new vertex.
* \param v (in) A handle to the created vertex.
*/
virtual void after_create_vertex(Vertex_handle /* v */)
{
virtual void after_create_vertex(Vertex_handle /* v */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -216,8 +207,7 @@ public:
/*! Notification after the creation of a new edge.
* \param e (in) A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge(Halfedge_handle /* e */)
{
virtual void after_create_edge(Halfedge_handle /* e */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -229,8 +219,7 @@ public:
* \param e2 (in) A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
Halfedge_handle /* e2 */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -244,8 +233,7 @@ public:
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{
bool /* is_hole */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -255,8 +243,7 @@ public:
/*! Notification after an outer CCB was created inside a face.
* \param h (in) A circulator representing the boundary of the new outer CCB.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */)
{
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -266,8 +253,7 @@ public:
/*! Notification after an edge was merged.
* \param e (in) A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge(Halfedge_handle /* e */)
{
virtual void after_merge_edge(Halfedge_handle /* e */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -277,8 +263,7 @@ public:
/*! Notification after a face was merged.
* \param f (in) A handle to the merged face.
*/
virtual void after_merge_face(Face_handle /* f */)
{
virtual void after_merge_face(Face_handle /* f */) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
@ -288,8 +273,7 @@ public:
/*! Notification after an outer CCB is moved from one face to another.
* \param h (in) A circulator representing the boundary of the component.
*/
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */)
{
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -299,8 +283,7 @@ public:
/*! Notificaion before the removal of a vertex.
* \param v (in) A handle to the vertex to be deleted.
*/
virtual void after_remove_vertex()
{
virtual void after_remove_vertex() override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
@ -310,8 +293,7 @@ public:
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be deleted.
*/
virtual void after_remove_edge()
{
virtual void after_remove_edge() override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -322,8 +304,7 @@ public:
/*! Notification before the removal of an outer CCB.
* \param f (in) The face that used to own the outer CCB.
*/
virtual void after_remove_outer_ccb(Face_handle /* f */)
{
virtual void after_remove_outer_ccb(Face_handle /* f */) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
@ -333,8 +314,7 @@ public:
/*! Notification after an inner CCB was created inside a face.
* \param h (in) A circulator representing the boundary of the new inner CCB.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */)
{
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -344,8 +324,7 @@ public:
/*! Notification after an inner CCB is moved from one face to another.
* \param h (in) A circulator representing the boundary of the component.
*/
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */)
{
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */) override {
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
@ -355,8 +334,7 @@ public:
/*! Notificaion after the removal of an inner CCB.
* \param f (in) The face that used to contain the inner CCB.
*/
virtual void after_remove_inner_ccb(Face_handle /* f */)
{
virtual void after_remove_inner_ccb(Face_handle /* f */) override {
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();

View File

@ -22,7 +22,6 @@
/*! \file
* Definition of the Arr_vertex_index_map<Arrangement> class.
*/
#include <CGAL/Arr_observer.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/property_map.h>
@ -35,26 +34,25 @@ namespace CGAL {
* arrangement vertices to the indices 0, ..., (n -1), where n is the number
* of vertices in the arrangement.
*/
template <class Arrangement_>
class Arr_vertex_index_map : public Arr_observer<Arrangement_>
{
template <typename Arrangement_>
class Arr_vertex_index_map : public Arrangement_::Observer {
public:
using Arrangement_2 = Arrangement_;
using Base_aos = typename Arrangement_2::Base_aos;
typedef Arrangement_ Arrangement_2;
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
using Vertex_handle = typename Base_aos::Vertex_handle;
// Boost property type definitions:
typedef boost::readable_property_map_tag category;
typedef unsigned int value_type;
typedef value_type reference;
typedef Vertex_handle key_type;
using category = boost::readable_property_map_tag;
using value_type = unsigned int;
using reference = value_type;
using key_type = Vertex_handle;
private:
using Self = Arr_vertex_index_map<Arrangement_2>;
using Base = typename Arrangement_2::Observer;
typedef Arr_vertex_index_map<Arrangement_2> Self;
typedef Arr_observer<Arrangement_2> Base;
typedef Unique_hash_map<Vertex_handle, unsigned int> Index_map;
using Index_map = Unique_hash_map<Vertex_handle, unsigned int>;
// Data members:
unsigned int n_vertices; // The current number of vertices.
@ -64,7 +62,6 @@ private:
enum {MIN_REV_MAP_SIZE = 32};
public:
/*! Default constructor. */
Arr_vertex_index_map() :
Base(),
@ -73,98 +70,84 @@ public:
{}
/*! Constructor with an associated arrangement. */
Arr_vertex_index_map (const Arrangement_2& arr) :
Base (const_cast<Arrangement_2&> (arr))
{
_init();
}
Arr_vertex_index_map(const Base_aos& arr) :
Base(const_cast<Base_aos&>(arr))
{ _init(); }
/*! Copy constructor. */
Arr_vertex_index_map(const Self& other) :
Base (const_cast<Arrangement_2&> (*(other.arrangement())))
{
_init();
}
Base(const_cast<Base_aos&>(*(other.arrangement())))
{ _init(); }
/*! Assignment operator. */
Self& operator= (const Self& other)
{
if (this == &other)
return (*this);
Self& operator= (const Self& other) {
if (this == &other) return (*this);
this->detach();
this->attach (const_cast<Arrangement_2&> (*(other.arrangement())));
this->attach(const_cast<Base_aos&>(*(other.arrangement())));
return (*this);
}
/*!
* Get the index of a given vertex.
/*! Get the index of a given vertex.
* \param v A handle to the vertex.
* \pre v is a valid vertex in the arrangement.
*/
unsigned int operator[] (Vertex_handle v) const
{
return index_map[v];
}
unsigned int operator[](Vertex_handle v) const { return index_map[v]; }
/*!
* Get the vertex given its index.
/*! Get the vertex given its index.
* \param i The index of the vertex.
* \pre i is less than the number of vertices in the graph.
*/
Vertex_handle vertex (const int i) const
{
Vertex_handle vertex(const int i) const {
CGAL_precondition(i < n_vertices);
return rev_map[i];
}
/// \name Notification functions, to keep the mapping up-to-date.
//@{
/*!
* Update the mapping after the arrangement has been assigned with another
/*! Update the mapping after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign ()
{
_init();
}
virtual void after_assign() override { _init(); }
/*!
* Update the mapping after the arrangement is cleared.
/*! Update the mapping after the arrangement is cleared.
*/
virtual void after_clear ()
{
_init();
}
virtual void after_clear() override { _init(); }
/*!
* Update the mapping after attaching to a new arrangement.
/*! Update the mapping after attaching to a new arrangement.
*/
virtual void after_attach ()
{
_init();
}
virtual void after_attach() override { _init(); }
/*!
* Update the mapping after detaching the arrangement.
/*! Update the mapping after detaching the arrangement.
*/
virtual void after_detach ()
{
virtual void after_detach() override {
n_vertices = 0;
index_map.clear();
}
/*!
* Update the mapping after the creation of a new vertex.
/*! Update the mapping after the creation of a new vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_vertex (Vertex_handle v)
{
virtual void after_create_vertex(Vertex_handle v) override {
// Update the number of vertices.
n_vertices++;
++n_vertices;
// If necessary, allocate memory for the reverse mapping.
if (rev_map.size() < n_vertices) rev_map.resize(2 * n_vertices);
// Update the mapping of the newly created vertex.
index_map[v] = n_vertices - 1;
rev_map[n_vertices - 1] = v;
}
/*! Update the mapping after the creation of a new boundary vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_boundary_vertex(Vertex_handle v) override {
// Update the number of vertices.
++n_vertices;
// If necessary, allocate memory for the reverse mapping.
if (rev_map.size() < n_vertices)
@ -175,32 +158,12 @@ public:
rev_map[n_vertices - 1] = v;
}
/*!
* Update the mapping after the creation of a new boundary vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_boundary_vertex (Vertex_handle v)
{
// Update the number of vertices.
n_vertices++;
// If necessary, allocate memory for the reverse mapping.
if (rev_map.size() < n_vertices)
rev_map.resize (2 * n_vertices);
// Update the mapping of the newly created vertex.
index_map[v] = n_vertices - 1;
rev_map[n_vertices - 1] = v;
}
/*!
* Update the mapping before the removal of a vertex.
/*! Update the mapping before the removal of a vertex.
* \param v A handle to the vertex to be removed.
*/
virtual void before_remove_vertex (Vertex_handle v)
{
virtual void before_remove_vertex(Vertex_handle v) override {
// Update the number of vertices.
n_vertices--;
--n_vertices;
// Reduce memory consumption in case the number of vertices has
// drastically decreased.
@ -214,8 +177,7 @@ public:
// currently indexed (n - 1).
unsigned int index = index_map[v];
if (index == n_vertices)
return;
if (index == n_vertices) return;
Vertex_handle last_v = rev_map[n_vertices];
index_map[last_v] = index;
@ -227,51 +189,42 @@ public:
//@}
private:
/*! Initialize the map for the given arrangement. */
void _init ()
{
void _init() {
// Get the number of vertices and allocate the reverse map accordingly.
n_vertices = static_cast<unsigned int>(this->arrangement()->number_of_vertices());
n_vertices =
static_cast<unsigned int>(this->arrangement()->number_of_vertices());
if (n_vertices < MIN_REV_MAP_SIZE)
rev_map.resize (MIN_REV_MAP_SIZE);
else
rev_map.resize (n_vertices);
if (n_vertices < MIN_REV_MAP_SIZE) rev_map.resize (MIN_REV_MAP_SIZE);
else rev_map.resize (n_vertices);
// Clear the current mapping.
index_map.clear();
// Create the initial mapping.
typename Arrangement_2::Vertex_iterator vit;
Vertex_handle vh;
unsigned int index = 0;
for (vit = this->arrangement()->vertices_begin();
vit != this->arrangement()->vertices_end(); ++vit, ++index)
{
for (auto vit = this->arrangement()->vertices_begin();
vit != this->arrangement()->vertices_end(); ++vit, ++index) {
// Map the current vertex to the current index.
vh = vit;
index_map[vh] = index;
rev_map[index] = vh;
}
}
};
/*!
* Get the index property-map function. Provided so that boost is able to
/*! Get the index property-map function. Provided so that boost is able to
* access the Arr_vertex_index_map above.
* \param index_map The index map.
* \param v A vertex handle.
* \return The vertex index.
*/
template<class Arrangement>
template <typename Arrangement>
unsigned int get(const CGAL::Arr_vertex_index_map<Arrangement>& index_map,
typename Arrangement::Vertex_handle v)
{
return index_map[v];
}
{ return index_map[v]; }
} //namespace CGAL

View File

@ -115,12 +115,9 @@ public:
typedef typename Base::Inner_ccb_const_iterator Hole_const_iterator;
private:
friend class Arr_observer<Self>;
friend class Arr_accessor<Self>;
public:
/// \name Constructors.
//@{
@ -215,34 +212,6 @@ public:
}
//@}
protected:
/// \name Managing and notifying the arrangement observers.
//@{
typedef Arr_observer<Self> Observer;
/*!
* Register a new observer (so it starts receiving notifications).
* \param p_obs A pointer to the observer object.
*/
void _register_observer (Observer *p_obs)
{
Base::_register_observer ((typename Base::Observer*)p_obs);
return;
}
/*!
* Unregister a new observer (so it stops receiving notifications).
* \param p_obs A pointer to the observer object.
* \return Whether the observer was successfully unregistered.
*/
bool _unregister_observer (Observer *p_obs)
{
return (Base::_unregister_observer ((typename Base::Observer*)p_obs));
}
//@}
};
} //namespace CGAL

View File

@ -273,29 +273,6 @@ bool Arrangement_on_surface_with_history_2<GeomTr,TopTr>::are_mergeable
e2->curve()));
}
//-----------------------------------------------------------------------------
// Register a new observer (so it starts receiving notifications).
//
template<class GeomTr, class TopTr>
void Arrangement_on_surface_with_history_2<GeomTr,TopTr>::
_register_observer(Arr_observer<Self> *p_obs)
{
Base_arr_2::_register_observer
(reinterpret_cast<Arr_observer<Base_arr_2>*>(p_obs));
return;
}
//-----------------------------------------------------------------------------
// Unregister an observer (so it stops receiving notifications).
//
template<class GeomTr, class TopTr>
bool Arrangement_on_surface_with_history_2<GeomTr,TopTr>::
_unregister_observer(Arr_observer<Self> *p_obs)
{
return (Base_arr_2::_unregister_observer
(reinterpret_cast<Arr_observer<Base_arr_2>*>(p_obs)));
}
} //namespace CGAL
#endif

View File

@ -40,7 +40,7 @@
#include <CGAL/Arrangement_2/Arrangement_2_iterators.h>
#include <CGAL/In_place_list.h>
#include <CGAL/Arr_default_dcel.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/Aos_observer.h>
#include <CGAL/Arr_accessor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/function_objects.h>
@ -109,8 +109,11 @@ public:
typedef typename Topology_traits::Dcel Dcel;
typedef typename Dcel::Size Size;
using Observer = Aos_observer<Self>;
using Base_aos = Self;
protected:
friend class Arr_observer<Self>;
friend class Aos_observer<Self>;
friend class Arr_accessor<Self>;
// Internal DCEL types:
@ -892,7 +895,6 @@ protected:
typedef CGAL_ALLOCATOR(Point_2) Points_alloc;
typedef CGAL_ALLOCATOR(X_monotone_curve_2) Curves_alloc;
typedef Arr_observer<Self> Observer;
typedef std::list<Observer*> Observers_container;
typedef typename Observers_container::iterator Observers_iterator;

View File

@ -26,7 +26,6 @@
#include <CGAL/Arrangement_on_surface_2.h>
#include <CGAL/Arr_overlay_2.h>
#include <CGAL/Arr_consolidated_curve_data_traits_2.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/In_place_list.h>
#include <CGAL/Arrangement_2/Arr_with_history_accessor.h>
@ -75,10 +74,7 @@ public:
typedef typename Geometry_traits_2::Curve_2 Curve_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Arr_observer<Self> Observer;
protected:
friend class Arr_observer<Self>;
friend class Arr_accessor<Self>;
friend class Arr_with_history_accessor<Self>;
@ -276,21 +272,19 @@ protected:
* involving edges and updates the list of halfedges associated with the
* input curves accordingly.
*/
class Curve_halfedges_observer : public Arr_observer<Base_arr_2> {
class Curve_halfedges_observer : public Base_arr_2::Observer {
public:
using Base_aos = typename Base_arr_2::Base_aos;
typedef typename Base_arr_2::Halfedge_handle Halfedge_handle;
typedef typename Base_arr_2::Vertex_handle Vertex_handle;
typedef typename Base_arr_2::X_monotone_curve_2 X_monotone_curve_2;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using X_monotone_curve_2 = typename Base_aos::X_monotone_curve_2;
/*!
* Notification after the creation of a new edge.
/*! Notification after the creation of a new edge.
* \param e A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge (Halfedge_handle e)
{
_register_edge(e);
}
virtual void after_create_edge(Halfedge_handle e) override
{ _register_edge(e); }
/*!
* Notification before the modification of an existing edge.
@ -298,22 +292,16 @@ protected:
* \param c The x-monotone curve to be associated with the edge.
*/
virtual void before_modify_edge(Halfedge_handle e,
const X_monotone_curve_2& /* c */)
{
_unregister_edge(e);
}
const X_monotone_curve_2& /* c */) override
{ _unregister_edge(e); }
/*!
* Notification after an edge was modified.
/*! Notification after an edge was modified.
* \param e A handle to one of the twin halfedges that were updated.
*/
virtual void after_modify_edge (Halfedge_handle e)
{
_register_edge(e);
}
virtual void after_modify_edge(Halfedge_handle e) override
{ _register_edge(e); }
/*!
* Notification before the splitting of an edge into two.
/*! Notification before the splitting of an edge into two.
* \param e A handle to one of the existing halfedges.
* \param c1 The x-monotone curve to be associated with the first edge.
* \param c2 The x-monotone curve to be associated with the second edge.
@ -321,66 +309,50 @@ protected:
virtual void before_split_edge(Halfedge_handle e,
Vertex_handle /* v */,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */)
{
_unregister_edge(e);
}
const X_monotone_curve_2& /* c2 */) override
{ _unregister_edge(e); }
/*!
* Notification after an edge was split.
/*! Notification after an edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle e1, Halfedge_handle e2)
{
override {
_register_edge(e1);
_register_edge(e2);
}
/*!
* Notification before the merging of two edges.
/*! Notification before the merging of two edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
* \param c The x-monotone curve to be associated with the merged edge.
*/
virtual void before_merge_edge(Halfedge_handle e1, Halfedge_handle e2,
const X_monotone_curve_2& /* c */)
{
const X_monotone_curve_2& /* c */) override {
_unregister_edge(e1);
_unregister_edge(e2);
}
/*!
* Notification after an edge was merged.
/*! Notification after an edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge (Halfedge_handle e)
{
_register_edge(e);
}
virtual void after_merge_edge(Halfedge_handle e) override
{ _register_edge(e); }
/*!
* Notification before the removal of an edge.
/*! Notification before the removal of an edge.
* \param e A handle to one of the twin halfedges to be deleted.
*/
virtual void before_remove_edge (Halfedge_handle e)
{
_unregister_edge(e);
}
virtual void before_remove_edge(Halfedge_handle e) override
{ _unregister_edge(e); }
private:
/*!
* Register the given halfedge in the set(s) associated with its curve.
/*! Register the given halfedge in the set(s) associated with its curve.
*/
void _register_edge (Halfedge_handle e)
{
Curve_halfedges *curve_halfedges;
Data_iterator di;
for (di = e->curve().data().begin(); di != e->curve().data().end(); ++di)
{
curve_halfedges = static_cast<Curve_halfedges*>(*di);
void _register_edge(Halfedge_handle e) {
for (auto di = e->curve().data().begin(); di != e->curve().data().end();
++di) {
Curve_halfedges* curve_halfedges = static_cast<Curve_halfedges*>(*di);
curve_halfedges->_insert(e);
}
}
@ -388,14 +360,10 @@ protected:
/*!
* Unregister the given halfedge from the set(s) associated with its curve.
*/
void _unregister_edge (Halfedge_handle e)
{
Curve_halfedges *curve_halfedges;
Data_iterator di;
for (di = e->curve().data().begin(); di != e->curve().data().end(); ++di)
{
curve_halfedges = static_cast<Curve_halfedges*>(*di);
void _unregister_edge(Halfedge_handle e) {
for (auto di = e->curve().data().begin(); di != e->curve().data().end();
++di) {
Curve_halfedges* curve_halfedges = static_cast<Curve_halfedges*>(*di);
curve_halfedges->_erase(e);
}
}
@ -582,24 +550,6 @@ public:
//@}
protected:
/// \name Managing and notifying the arrangement observers.
//@{
/*!
* Register a new observer (so it starts receiving notifications).
* \param p_obs A pointer to the observer object.
*/
void _register_observer (Observer *p_obs);
/*!
* Unregister an observer (so it stops receiving notifications).
* \param p_obs A pointer to the observer object.
* \return Whether the observer was successfully unregistered.
*/
bool _unregister_observer (Observer *p_obs);
//@}
/// \name Curve insertion and deletion.
//@{

View File

@ -119,7 +119,6 @@ public:
private:
typedef Arrangement_with_history_2<Geometry_traits_2, Dcel> Self;
friend class Arr_observer<Self>;
friend class Arr_accessor<Self>;
public:
@ -233,35 +232,8 @@ public:
return (Face_const_handle (p_oc->face()));
}
//@}
protected:
/// \name Managing and notifying the arrangement observers.
//@{
typedef Arr_observer<Self> Observer;
/*!
* Register a new observer (so it starts receiving notifications).
* \param p_obs A pointer to the observer object.
*/
void _register_observer (Observer *p_obs)
{
Base::_register_observer ((typename Base::Observer*)p_obs);
return;
}
/*!
* Unregister a new observer (so it stops receiving notifications).
* \param p_obs A pointer to the observer object.
* \return Whether the observer was successfully unregistered.
*/
bool _unregister_observer (Observer *p_obs)
{
return (Base::_unregister_observer ((typename Base::Observer*)p_obs));
}
//@}
};
} //namespace CGAL

View File

@ -5,7 +5,6 @@
#include <CGAL/MP_Float.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/Arr_enums.h>
#include <iostream>
@ -34,21 +33,18 @@ typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
void skip_comments(std::ifstream & is, char * line)
{
void skip_comments(std::ifstream & is, char* line) {
while (!is.eof()) {
is.getline(line, 128);
if (line[0] != '#') break;
}
}
void compare_results(std::string str)
{
void compare_results(std::string str) {
skip_comments(global_input_file, one_line);
std::istringstream str_stream(one_line);
str_stream.getline(buff, 128, ' ');
if (std::string(buff)!=str)
{
if (std::string(buff) != str) {
std::cout << "Expected " << std::string(buff) << " obtained "
<< str << std::endl;
ok = -1;
@ -57,212 +53,158 @@ void compare_results(std::string str)
// An arrangement observer, used to receive notifications of face splits and
// face mergers.
class Test_observer : public CGAL::Arr_observer<Arrangement_2>
{
class Test_observer : public Arrangement_2::Observer {
public:
using Observer = Arrangement_2::Observer;
using Base_aos = Arrangement_2::Base_aos;
Test_observer (Arrangement_2& arr) :
CGAL::Arr_observer<Arrangement_2> (arr)
{}
using Vertex_handle = Base_aos::Vertex_handle;
using Halfedge_handle = Base_aos::Halfedge_handle;
using Face_handle = Base_aos::Face_handle;
using Ccb_halfedge_circulator = Base_aos::Ccb_halfedge_circulator;
using Point_2 = Base_aos::Point_2;
using X_monotone_curve_2 = Base_aos::X_monotone_curve_2;
Test_observer(Base_aos& arr) : Observer(arr) {}
/// \name Notification functions on global arrangement operations.
//@{
/*!
* Notification before the arrangement is assigned with another
* arrangement.
* \param arr The arrangement to be copied.
/*! Notification before the arrangement is assigned with the content of
* another arrangement.
* \param arr The other arrangement. Notice that the arrangement type is the
* type used to instantiate the observer, which is conveniently
* defined as `Arrangement_2::Base_aos`.
*/
virtual void before_assign (const Arrangement_2& /* arr */)
{
compare_results("before_assign");
}
virtual void before_assign(const Base_aos& /* arr */) override
{ compare_results("before_assign"); }
/*!
* Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign ()
{
compare_results("after_assign");
}
virtual void after_assign() override { compare_results("after_assign"); }
/*! Notification before the arrangement is cleared. */
virtual void before_clear ()
{
compare_results("before_clear");
}
virtual void before_clear() override { compare_results("before_clear"); }
/*!
* Notification after the arrangement is cleared.
*/
virtual void after_clear ()
{
compare_results("after_clear");
}
virtual void after_clear() override { compare_results("after_clear"); }
/*! Notification before a global operation modifies the arrangement. */
virtual void before_global_change ()
{
compare_results("before_global_change");
}
virtual void before_global_change() override
{ compare_results("before_global_change"); }
/*! Notification after a global operation is completed. */
virtual void after_global_change ()
{
compare_results("after_global_change");
}
virtual void after_global_change() override
{ compare_results("after_global_change"); }
//@}
/// \name Notification functions on observer attachment or detachment.
//@{
/*!
* Notification before the observer is attached to an arrangement.
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement we are about to attach the observer to.
*/
virtual void before_attach (const Arrangement_2& /* arr */)
{
compare_results("before_attach");
}
virtual void before_attach(const Base_aos& /* arr */) override
{ compare_results("before_attach"); }
/*!
* Notification after the observer has been attached to an arrangement.
/*! Notification after the observer has been attached to an arrangement.
*/
virtual void after_attach ()
{
compare_results("after_attach");
}
virtual void after_attach() override { compare_results("after_attach"); }
/*!
* Notification before the observer is detached from the arrangement.
/*! Notification before the observer is detached from the arrangement.
*/
virtual void before_detach ()
{
compare_results("before_detach");
}
virtual void before_detach() override { compare_results("before_detach"); }
/*!
* Notification after the observer has been detached to the arrangement.
/*! Notification after the observer has been detached to the arrangement.
*/
virtual void after_detach ()
{
compare_results("after_detach");
}
virtual void after_detach() override { compare_results("after_detach"); }
//@}
/// \name Notification functions on local changes in the arrangement.
//@{
/*!
* Notification before the creation of a new vertex.
/*! Notification before the creation of a new vertex.
* \param p The point to be associated with the vertex.
* This point cannot lies on the surface boundaries.
*/
virtual void before_create_vertex (const Point_2& /* p */)
{
compare_results("before_create_vertex");
}
virtual void before_create_vertex(const Point_2& /* p */) override
{ compare_results("before_create_vertex"); }
/*!
* Notification after the creation of a new vertex.
/*! Notification after the creation of a new vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_vertex (Vertex_handle /* v */)
{
compare_results("after_create_vertex");
}
virtual void after_create_vertex(Vertex_handle /* v */) override
{ compare_results("after_create_vertex"); }
/*!
* Notification before the creation of a new boundary vertex.
/*! Notification before the creation of a new boundary vertex.
* \param cv The curve incident to the surface boundary.
* \param ind The relevant curve-end.
* \param bound_x The boundary condition of the vertex in x.
* \param bound_y The boundary condition of the vertex in y.
*/
virtual void before_create_boundary_vertex (const X_monotone_curve_2& /*cv*/,
virtual void
before_create_boundary_vertex(const X_monotone_curve_2& /*cv*/,
CGAL::Arr_curve_end /* ind */,
CGAL::Arr_parameter_space /* bound_x */,
CGAL::Arr_parameter_space /* bound_y */)
{
compare_results("before_create_boundary_vertex");
}
override
{ compare_results("before_create_boundary_vertex"); }
/*!
* Notification after the creation of a new vertex at infinity.
/*! Notification after the creation of a new vertex at infinity.
* \param v A handle to the created vertex.
*/
virtual void after_create_boundary_vertex (Vertex_handle /* v */)
{
compare_results("after_create_boundary_vertex");
}
virtual void after_create_boundary_vertex(Vertex_handle /* v */) override
{ compare_results("after_create_boundary_vertex"); }
/*!
* Notification before the creation of a new edge.
/*! Notification before the creation of a new edge.
* \param c The x-monotone curve to be associated with the edge.
* \param v1 A handle to the first end-vertex of the edge.
* \param v2 A handle to the second end-vertex of the edge.
*/
virtual void before_create_edge(const X_monotone_curve_2& /* c */,
Vertex_handle /* v1 */,
Vertex_handle /* v2 */)
{
compare_results("before_create_edge");
}
Vertex_handle /* v2 */) override
{ compare_results("before_create_edge"); }
/*!
* Notification after the creation of a new edge.
/*! Notification after the creation of a new edge.
* \param e A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge (Halfedge_handle /* e */)
{
compare_results("after_create_edge");
}
virtual void after_create_edge(Halfedge_handle /* e */) override
{ compare_results("after_create_edge"); }
/*!
* Notification before the modification of an existing vertex.
/*! Notification before the modification of an existing vertex.
* \param v A handle to the vertex to be updated.
* \param p The point to be associated with the vertex.
*/
virtual void before_modify_vertex(Vertex_handle /* v */,
const Point_2& /* p */)
{
compare_results("before_modify_vertex");
}
const Point_2& /* p */) override
{ compare_results("before_modify_vertex"); }
/*!
* Notification after a vertex was modified.
/*! Notification after a vertex was modified.
* \param v A handle to the updated vertex.
*/
virtual void after_modify_vertex (Vertex_handle /* v */)
{
compare_results("after_modify_vertex");
}
virtual void after_modify_vertex(Vertex_handle /* v */) override
{ compare_results("after_modify_vertex"); }
/*!
* Notification before the modification of an existing edge.
/*! Notification before the modification of an existing edge.
* \param e A handle to one of the twin halfedges to be updated.
* \param c The x-monotone curve to be associated with the edge.
*/
virtual void before_modify_edge(Halfedge_handle /* e */,
const X_monotone_curve_2& /* c */)
{
compare_results("before_modify_edge");
}
const X_monotone_curve_2& /* c */) override
{ compare_results("before_modify_edge"); }
/*!
* Notification after an edge was modified.
/*! Notification after an edge was modified.
* \param e A handle to one of the twin halfedges that were updated.
*/
virtual void after_modify_edge (Halfedge_handle /* e */)
{
compare_results("after_modify_edge");
}
virtual void after_modify_edge(Halfedge_handle /* e */) override
{ compare_results("after_modify_edge"); }
/*!
* Notification before the splitting of an edge into two.
/*! Notification before the splitting of an edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the split point.
* \param c1 The x-monotone curve to be associated with the first edge.
@ -271,201 +213,148 @@ public:
virtual void before_split_edge(Halfedge_handle /* e */,
Vertex_handle /* v */,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */)
{
compare_results("before_split_edge");
}
const X_monotone_curve_2& /* c2 */) override
{ compare_results("before_split_edge"); }
/*!
* Notification after an edge was split.
/*! Notification after an edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
compare_results("after_split_edge");
}
Halfedge_handle /* e2 */) override
{ compare_results("after_split_edge"); }
/*!
* Notification before the splitting of a fictitious edge into two.
/*! Notification before the splitting of a fictitious edge into two.
* \param e A handle to one of the existing halfedges.
* \param v A vertex representing the unbounded split point.
*/
virtual void before_split_fictitious_edge(Halfedge_handle /* e */,
Vertex_handle /* v */)
{
compare_results("before_split_fictitious_edge");
}
Vertex_handle /* v */) override
{ compare_results("before_split_fictitious_edge"); }
/*!
* Notification after a fictitious edge was split.
/*! Notification after a fictitious edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
compare_results("after_split_fictitious_edge");
}
Halfedge_handle /* e2 */) override
{ compare_results("after_split_fictitious_edge"); }
/*!
* Notification before the splitting of a face into two.
/*! Notification before the splitting of a face into two.
* \param f A handle to the existing face.
* \param e The new edge whose insertion causes the face to split.
*/
virtual void before_split_face(Face_handle /* f */,
Halfedge_handle /* e */)
{
compare_results("before_split_face");
}
Halfedge_handle /* e */) override
{ compare_results("before_split_face"); }
/*!
* Notification after a face was split.
/*! Notification after a face was split.
* \param f A handle to the face we have just split.
* \param new_f A handle to the new face that has been created.
* \param is_hole Whether the new face forms a hole inside f.
*/
virtual void after_split_face (Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{
compare_results("after_split_face");
}
bool /* is_hole */) override
{ compare_results("after_split_face"); }
/*!
* Notification before the splitting of an outer CCB into two.
/*! Notification before the splitting of an outer CCB into two.
* \param f A handle to the face that owns the outer CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the outer CCB to split.
*/
virtual void before_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{
compare_results("before_split_outer_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_split_outer_ccb"); }
/*!
* Notification after an outer CCB was split.
/*! Notification after an outer CCB was split.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{
compare_results("after_split_outer_ccb");
}
Ccb_halfedge_circulator /* h2 */) override
{ compare_results("after_split_outer_ccb"); }
/*!
* Notification before the splitting of an inner CCB into two.
/*! Notification before the splitting of an inner CCB into two.
* \param f A handle to the face containing the inner CCB.
* \param h A circulator representing the component boundary.
* \param e The new edge whose removal causes the inner CCB to split.
*/
virtual void before_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */,
Halfedge_handle /* e */)
{
compare_results("before_split_inner_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_split_inner_ccb"); }
/*!
* Notification after an inner CCB was split.
/*! Notification after an inner CCB was split.
* \param f A handle to the face containing the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
*/
virtual void after_split_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */)
{
compare_results("after_split_inner_ccb");
}
Ccb_halfedge_circulator /* h2 */) override
{ compare_results("after_split_inner_ccb"); }
/*!
* Notification before the creation of a new outer CCB of a face.
/*! Notification before the creation of a new outer CCB of a face.
* \param f A handle to the face that owns the outer CCB.
* \param e A halfedge along the new outer CCB.
*/
virtual void before_add_outer_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{
compare_results("before_add_outer_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_add_outer_ccb"); }
/*!
* Notification after an outer CCB was added to a face.
/*! Notification after an outer CCB was added to a face.
* \param h A circulator representing the boundary of the new outer CCB.
*/
virtual void after_add_outer_ccb (Ccb_halfedge_circulator /* h */)
{
compare_results("after_add_outer_ccb");
}
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */) override
{ compare_results("after_add_outer_ccb"); }
/*!
* Notification before the creation of a new inner CCB inside a face.
/*! Notification before the creation of a new inner CCB inside a face.
* \param f A handle to the face containing the inner CCB.
* \param e The new halfedge that forms the new inner CCB.
*/
virtual void before_add_inner_ccb(Face_handle /* f */,
Halfedge_handle /* e */)
{
compare_results("before_add_inner_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_add_inner_ccb"); }
/*!
* Notification after an inner CCB was created inside a face.
/*! Notification after an inner CCB was created inside a face.
* \param h A circulator representing the boundary of the new inner CCB.
*/
virtual void after_add_inner_ccb (Ccb_halfedge_circulator /* h */)
{
compare_results("after_add_inner_ccb");
}
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */) override
{ compare_results("after_add_inner_ccb"); }
/*!
* Notification before the creation of a new isolated vertex inside a face.
/*! Notification before the creation of a new isolated vertex inside a face.
* \param f A handle to the face containing the isolated vertex.
* \param v The isolated vertex.
*/
virtual void before_add_isolated_vertex(Face_handle /* f */,
Vertex_handle /* v */)
{
compare_results("before_add_isolated_vertex");
}
Vertex_handle /* v */) override
{ compare_results("before_add_isolated_vertex"); }
/*!
* Notification after an isolated vertex was created inside a face.
/*! Notification after an isolated vertex was created inside a face.
* \param v The isolated vertex.
*/
virtual void after_add_isolated_vertex (Vertex_handle /* v */)
{
compare_results("after_add_isolated_vertex");
}
virtual void after_add_isolated_vertex(Vertex_handle /* v */) override
{ compare_results("after_add_isolated_vertex"); }
/*!
* Notification before the merging of two edges.
/*! Notification before the merging of two edges.
* \param e1 A handle to one of the halfedges forming the first edge.
* \param e2 A handle to one of the halfedges forming the second edge.
* \param c The x-monotone curve to be associated with the merged edge.
*/
virtual void before_merge_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */,
const X_monotone_curve_2& /* c */)
{
compare_results("before_merge_edge");
}
const X_monotone_curve_2& /* c */) override
{ compare_results("before_merge_edge"); }
/*!
* Notification after an edge was merged.
/*! Notification after an edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge (Halfedge_handle /* e */)
{
compare_results("after_merge_edge");
}
virtual void after_merge_edge(Halfedge_handle /* e */) override
{ compare_results("after_merge_edge"); }
/*!
* Notification before the merging of two fictitious edges.
@ -473,44 +362,32 @@ public:
* \param e2 A handle to one of the halfedges forming the second edge.
*/
virtual void before_merge_fictitious_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
compare_results("before_merge_fictitious_edge");
}
Halfedge_handle /* e2 */) override
{ compare_results("before_merge_fictitious_edge"); }
/*!
* Notification after a fictitious edge was merged.
/*! Notification after a fictitious edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_fictitious_edge (Halfedge_handle /* e */)
{
compare_results("after_merge_fictitious_edge");
}
virtual void after_merge_fictitious_edge (Halfedge_handle /* e */) override
{ compare_results("after_merge_fictitious_edge"); }
/*!
* Notification before the merging of two faces.
/*! Notification before the merging of two faces.
* \param f1 A handle to the first face.
* \param f2 A handle to the second face.
* \param e The edge whose removal causes the faces to merge.
*/
virtual void before_merge_face(Face_handle /* f1 */,
Face_handle /* f2 */,
Halfedge_handle /* e */)
{
compare_results("before_merge_face");
}
Halfedge_handle /* e */) override
{ compare_results("before_merge_face"); }
/*!
* Notification after a face was merged.
/*! Notification after a face was merged.
* \param f A handle to the merged face.
*/
virtual void after_merge_face (Face_handle /* f */)
{
compare_results("after_merge_face");
}
virtual void after_merge_face(Face_handle /* f */) override
{ compare_results("after_merge_face"); }
/*!
* Notification before the merging of two outer CCBs.
/*! Notification before the merging of two outer CCBs.
* \param f A handle to the face that owns the outer CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
@ -519,24 +396,18 @@ public:
virtual void before_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{
compare_results("before_merge_outer_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_merge_outer_ccb"); }
/*!
* Notification after an outer CCB was merged.
/*! Notification after an outer CCB was merged.
* \param f A handle to the face that owns the outer CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("after_merge_outer_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("after_merge_outer_ccb"); }
/*!
* Notification before the merging of two inner CCBs (holes).
/*! Notification before the merging of two inner CCBs (holes).
* \param f A handle to the face that contains the inner CCBs.
* \param h1 A circulator representing the boundary of the first component.
* \param h2 A circulator representing the boundary of the second component.
@ -545,176 +416,126 @@ public:
virtual void before_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h1 */,
Ccb_halfedge_circulator /* h2 */,
Halfedge_handle /* e */)
{
compare_results("before_merge_inner_ccb");
}
Halfedge_handle /* e */) override
{ compare_results("before_merge_inner_ccb"); }
/*!
* Notification after an inner CCB was merged.
/*! Notification after an inner CCB was merged.
* \param f A handle to the face that contains the inner CCBs.
* \param h A circulator representing the boundary of the merged component.
*/
virtual void after_merge_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("after_merge_inner_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("after_merge_inner_ccb"); }
/*!
* Notification before an outer CCB is moved from one face to another.
/*! Notification before an outer CCB is moved from one face to another.
* \param from_f A handle to the face that currently owns the outer CCB.
* \param to_f A handle to the face that should own the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_outer_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("before_move_outer_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("before_move_outer_ccb"); }
/*!
* Notification after an outer CCB is moved from one face to another.
/*! Notification after an outer CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_outer_ccb (Ccb_halfedge_circulator /* h */)
{
compare_results("after_move_outer_ccb");
}
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */) override
{ compare_results("after_move_outer_ccb"); }
/*!
* Notification before an inner CCB is moved from one face to another.
/*! Notification before an inner CCB is moved from one face to another.
* \param from_f A handle to the face currently containing the inner CCB.
* \param to_f A handle to the face that should contain the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_move_inner_ccb(Face_handle /* from_f */,
Face_handle /* to_f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("before_move_inner_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("before_move_inner_ccb"); }
/*!
* Notification after an inner CCB is moved from one face to another.
/*! Notification after an inner CCB is moved from one face to another.
* \param h A circulator representing the boundary of the component.
*/
virtual void after_move_inner_ccb (Ccb_halfedge_circulator /* h */)
{
compare_results("after_move_inner_ccb");
}
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */) override
{ compare_results("after_move_inner_ccb"); }
/*!
* Notification before an isolated vertex is moved from one face to another.
/*! Notification before an isolated vertex is moved from one face to another.
* \param from_f A handle to the face currently containing the vertex.
* \param to_f A handle to the face that should contain the vertex.
* \param v The isolated vertex.
*/
virtual void before_move_isolated_vertex(Face_handle /* from_f */,
Face_handle /* to_f */,
Vertex_handle /* v */)
{
compare_results("before_move_isolated_vertex");
}
Vertex_handle /* v */) override
{ compare_results("before_move_isolated_vertex"); }
/*!
* Notification after an isolated vertex is moved from one face to another.
/*! Notification after an isolated vertex is moved from one face to another.
* \param v The isolated vertex.
*/
virtual void after_move_isolated_vertex (Vertex_handle /* v */)
{
compare_results("after_move_isolated_vertex");
}
virtual void after_move_isolated_vertex(Vertex_handle /* v */) override
{ compare_results("after_move_isolated_vertex"); }
/*!
* Notificaion before the removal of a vertex.
/*! Notificaion before the removal of a vertex.
* \param v A handle to the vertex to be deleted.
*/
virtual void before_remove_vertex (Vertex_handle /* v */)
{
compare_results("before_remove_vertex");
}
virtual void before_remove_vertex(Vertex_handle /* v */) override
{ compare_results("before_remove_vertex"); }
/*!
* Notificaion after the removal of a vertex.
/*! Notificaion after the removal of a vertex.
*/
virtual void after_remove_vertex ()
{
compare_results("after_remove_vertex");
}
virtual void after_remove_vertex() override
{ compare_results("after_remove_vertex"); }
/*!
* Notification before the removal of an edge.
/*! Notification before the removal of an edge.
* \param e A handle to one of the twin halfedges to be deleted.
*/
virtual void before_remove_edge (Halfedge_handle /* e */)
{
compare_results("before_remove_edge");
}
virtual void before_remove_edge(Halfedge_handle /* e */) override
{ compare_results("before_remove_edge"); }
/*!
* Notificaion after the removal of an edge.
/*! Notificaion after the removal of an edge.
*/
virtual void after_remove_edge ()
{
compare_results("after_remove_edge");
}
virtual void after_remove_edge() override
{ compare_results("after_remove_edge"); }
/*!
* Notification before the removal of an outer CCB.
/*! Notification before the removal of an outer CCB.
* \param f The face that owns the outer CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_outer_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("before_remove_outer_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("before_remove_outer_ccb"); }
/*!
* Notificaion after the removal of an outer CCB.
/*! Notificaion after the removal of an outer CCB.
* \param f The face that used to own the outer CCB.
*/
virtual void after_remove_outer_ccb (Face_handle /* f */)
{
compare_results("after_remove_outer_ccb");
}
virtual void after_remove_outer_ccb(Face_handle /* f */) override
{ compare_results("after_remove_outer_ccb"); }
/*!
* Notification before the removal of an inner CCB.
/*! Notification before the removal of an inner CCB.
* \param f The face containing the inner CCB.
* \param h A circulator representing the boundary of the component.
*/
virtual void before_remove_inner_ccb(Face_handle /* f */,
Ccb_halfedge_circulator /* h */)
{
compare_results("before_remove_inner_ccb");
}
Ccb_halfedge_circulator /* h */) override
{ compare_results("before_remove_inner_ccb"); }
/*!
* Notificaion after the removal of an inner CCB.
/*! Notificaion after the removal of an inner CCB.
* \param f The face that used to contain the inner CCB.
*/
virtual void after_remove_inner_ccb (Face_handle /* f */)
{
compare_results("after_remove_inner_ccb");
}
virtual void after_remove_inner_ccb(Face_handle /* f */) override
{ compare_results("after_remove_inner_ccb"); }
//@}
};
int main (int argc, char * argv[])
{
if (argc != 2)
{
int main (int argc, char* argv[]) {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " inputfile" << std::endl;
CGAL_error();
}
else
{
else {
// Construct the arrangement containing one diamond-shaped face.
Arrangement_2 arr;
global_input_file.open(argv[1]);
@ -725,55 +546,48 @@ int main (int argc, char * argv[])
int i_vh = 0, i_heh = 0;
std::vector<Arrangement_2::Halfedge_handle> heh_vec;
std::vector<Arrangement_2::Vertex_handle> vh_vec;
while (!global_input_file.eof())
{
while (! global_input_file.eof()) {
skip_comments(global_input_file, one_line);
std::istringstream str_stream(one_line);
char c;
str_stream >> c;
if (!global_input_file.gcount())
break;
if (c=='s')
{
if (c=='s') {
str_stream >> c;
//read segment
str_stream >> s;
if (c=='i')
{
if (c=='i') {
// si means insert intersecting segment
insert(arr,s);
std::cout << "intersecting segment insert " << s << std::endl;
}
else if (c=='n')
{
else if (c=='n') {
// sn means insert non intersecting segment
heh_vec.push_back(insert_non_intersecting_curve (arr, s));
std::cout << "non intersecting segment insert " << s << std::endl;
}
}
else if (c=='p')
{
else if (c=='p') {
// p means read point
str_stream >> p ;
std::cout << "point insert " << p << " index " << vh_vec.size() << std::endl;
std::cout << "point insert " << p << " index " << vh_vec.size()
<< std::endl;
vh_vec.push_back(insert_point(arr,p));
}
else if (c=='e')
{
else if (c=='e') {
// e means read edge index to be removed
str_stream >> i_heh ;
std::cout << "remove edge " << heh_vec[i_heh]->curve() << std::endl;
remove_edge(arr,heh_vec[i_heh]);
}
else if (c=='v')
{
else if (c=='v') {
// v means read point index to be removed
str_stream >> i_vh ;
std::cout << "remove point " << vh_vec[i_vh]->point() << std::endl;
remove_vertex(arr,vh_vec[i_vh]);
}
else
{
else {
//error
std::cout << "error, unknowen command" << std::endl;
return -1;

View File

@ -28,7 +28,6 @@
#include <time.h>
#include <CGAL/enum.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/Envelope_3/Envelope_base.h>
#include <CGAL/Envelope_3/Envelope_overlay_2.h>
#include <CGAL/Envelope_3/Envelope_element_visitor_3.h>
@ -134,7 +133,8 @@ protected:
typedef typename Minimization_diagram_2::Inner_ccb_iterator
Inner_ccb_iterator;
typedef Arr_observer<Minimization_diagram_2> Md_observer;
typedef typename Minimization_diagram_2::Observer
Md_observer;
typedef typename Minimization_diagram_2::Dcel::Dcel_data_iterator
Envelope_data_iterator;
@ -1584,19 +1584,16 @@ protected:
// observer for the minimization diagram
// keeps the relevant data in the new faces
class Keep_face_data_observer : public Md_observer
{
class Keep_face_data_observer : public Md_observer {
public:
typedef typename Minimization_diagram_2::Face_handle Face_handle;
using Base_aos = typename Minimization_diagram_2::Base_aos;
using Face_handle = typename Base_aos::Face_handle;
Keep_face_data_observer(Minimization_diagram_2& arr) :
Md_observer(arr)
{}
Keep_face_data_observer(Base_aos& arr) : Md_observer(arr) {}
virtual void after_split_face(Face_handle org_f,
Face_handle new_f,
bool /* is_hole*/)
{
bool /* is_hole*/) override {
// update data in the new face from the original face
if (org_f->get_aux_is_set(0))
new_f->set_aux_source(0, org_f->get_aux_source(0));
@ -1610,24 +1607,20 @@ protected:
// observer for the minimization diagram
// keeps the relevant data in the new edges & vertices
class Keep_edge_data_observer : public Md_observer
{
class Keep_edge_data_observer : public Md_observer {
public:
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle;
typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle;
typedef typename Minimization_diagram_2::X_monotone_curve_2
X_monotone_curve_2;
using Base_aos = typename Minimization_diagram_2::Base_aos;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using X_monotone_curve_2 = typename Base_aos::X_monotone_curve_2;
typedef typename Envelope_divide_and_conquer_3<Traits,
using Self = typename Envelope_divide_and_conquer_3<Traits,
Minimization_diagram_2,
EnvelopeResolver_3,
Overlay_2>::Self Self;
Keep_edge_data_observer(Minimization_diagram_2& arr,
Self* b) :
Overlay_2>::Self;
Keep_edge_data_observer(Base_aos& arr, Self* b) :
Md_observer(arr), base(b)
{
CGAL_assertion(base != nullptr);
}
{ CGAL_assertion(base != nullptr); }
/* virtual void before_split_edge(Halfedge_handle e,
* Vertex_handle v,
@ -1637,7 +1630,7 @@ protected:
*/
virtual void after_split_edge(Halfedge_handle he1, Halfedge_handle he2)
{
override {
// update data of the new vertex, which is the common vertex of he1 and
// he2, and of the new edge according to the data in the original edge
CGAL_assertion(he2->source() == he1->target());
@ -1657,20 +1650,17 @@ protected:
// the second halfedge
Halfedge_handle org_he = he1, new_he = he2;
if (org_he->is_decision_set())
{
if (org_he->is_decision_set()) {
new_he->set_decision(org_he->get_decision());
new_he->twin()->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_he->set_aux_source(0, org_he->get_aux_source(0));
new_he->twin()->set_aux_source(0, org_he->twin()->get_aux_source(0));
}
if (org_he->get_aux_is_set(1))
{
if (org_he->get_aux_is_set(1)) {
new_vertex->set_aux_source(1, org_he->get_aux_source(1));
new_he->set_aux_source(1, org_he->get_aux_source(1));
new_he->twin()->set_aux_source(1, org_he->twin()->get_aux_source(1));

View File

@ -20,7 +20,6 @@
#include <CGAL/enum.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/Arr_accessor.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Arr_naive_point_location.h>
@ -96,7 +95,7 @@ protected:
typedef typename Minimization_diagram_2::Dcel::Dcel_data_iterator
Envelope_data_iterator;
typedef Arr_observer<Minimization_diagram_2> Md_observer;
typedef typename Minimization_diagram_2::Observer Md_observer;
typedef Arr_accessor<Minimization_diagram_2> Md_accessor;
typedef typename Topology_traits::Default_point_location_strategy
@ -1979,14 +1978,13 @@ protected:
// so we can later identify all the faces that form the original given face
// it also should remember the edges of the face, that are also projected
// intersections
class Copied_face_observer : public Md_observer
{
class Copied_face_observer : public Md_observer {
public:
typedef typename Minimization_diagram_2::Face_handle Face_handle;
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle;
typedef typename Minimization_diagram_2::X_monotone_curve_2
X_monotone_curve_2;
using Base_aos = typename Minimization_diagram_2::Base_aos;
using Face_handle = typename Base_aos::Face_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using X_monotone_curve_2 = typename Base_aos::X_monotone_curve_2;
Copied_face_observer(Halfedges_map& map_h) : map_halfedges(map_h) {}
@ -1998,8 +1996,7 @@ protected:
Faces_hash& parts,
Vertices_hash& boundaryv,
Vertices_hash& specialv,
Vertices_to_edges_map& v_to_h)
{
Vertices_to_edges_map& v_to_h) {
boundary_halfedges = &boundary;
special_edges = &specialh;
new_edges = &newh;
@ -2010,20 +2007,16 @@ protected:
}
virtual void after_split_face(Face_handle org_f,
Face_handle new_f, bool)
{
Face_handle new_f, bool) override {
// keep track of the face parts
if (face_parts->is_defined(org_f))
(*face_parts)[new_f] = face_parts->default_value();
}
virtual void after_split_edge(Halfedge_handle org_he,
Halfedge_handle new_he)
{
Halfedge_handle new_he) override {
// take care of special edges that were split
if (special_edges->is_defined(org_he))
{
if (special_edges->is_defined(org_he)) {
// if original edge was in the set, then now both split parts should
// be in the set
(*special_edges)[new_he] = special_edges->default_value();
@ -2031,15 +2024,13 @@ protected:
}
// take care of new edges that were split
if (new_edges->is_defined(org_he))
{
if (new_edges->is_defined(org_he)) {
(*new_edges)[new_he] = (*new_edges)[org_he];
(*new_edges)[new_he->twin()] = (*new_edges)[org_he];
}
// take care for boundary edges
if (boundary_halfedges->is_defined(org_he))
{
if (boundary_halfedges->is_defined(org_he)) {
(*boundary_halfedges)[new_he] = boundary_halfedges->default_value();
(*boundary_halfedges)[new_he->twin()] =
boundary_halfedges->default_value();
@ -2066,8 +2057,7 @@ protected:
Halfedge_handle correct_side_he;
if (face_parts->is_defined(org_he->face()))
correct_side_he = org_he;
else
{
else {
CGAL_assertion(face_parts->is_defined(new_he->twin()->face()));
// new_he->twin() is directed as org_he, so on the boundary pointing
// inside the face, and has the new vertex as target
@ -2080,7 +2070,8 @@ protected:
//BZBZ
/* CGAL_assertion(vertices_to_halfedges->is_defined(correct_side_he->source()) &&
vertices_to_halfedges->is_defined(correct_side_he->next()->target()));*/
(*vertices_to_halfedges)[correct_side_he->next()->target()] = correct_side_he->next();
(*vertices_to_halfedges)[correct_side_he->next()->target()] =
correct_side_he->next();
if (correct_side_he == org_he &&
face_parts->is_defined(org_he->twin()->face()))
@ -2100,33 +2091,31 @@ protected:
Halfedges_map& map_halfedges;
};
// this observer is used in the process of resolving a face
// it listens to what happens in the copied arrangement, and copies back
// the actions to result arrangements very efficiently
class Copy_observer : public Md_observer
{
class Copy_observer : public Md_observer {
public:
typedef typename Minimization_diagram_2::Face_handle Face_handle;
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle;
typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle;
typedef typename Minimization_diagram_2::Point_2 Point_2;
typedef typename Minimization_diagram_2::X_monotone_curve_2
X_monotone_curve_2;
typedef typename Minimization_diagram_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
using Base_aos = typename Minimization_diagram_2::Base_aos;
typedef typename Traits::Left_side_category Left_side_category;
typedef typename Traits::Right_side_category Right_side_category;
typedef typename Traits::Top_side_category Top_side_category;
typedef typename Traits::Bottom_side_category Bottom_side_category;
using Face_handle = typename Base_aos::Face_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Point_2 = typename Base_aos::Point_2;
using X_monotone_curve_2 = typename Base_aos::X_monotone_curve_2;
using Ccb_halfedge_circulator = typename Base_aos::Ccb_halfedge_circulator;
using Left_side_category = typename Traits::Left_side_category;
using Right_side_category = typename Traits::Right_side_category;
using Top_side_category = typename Traits::Top_side_category;
using Bottom_side_category = typename Traits::Bottom_side_category;
Copy_observer(Minimization_diagram_2& small_,
Minimization_diagram_2& big,
Halfedges_map& map_h,
Vertices_map& map_v,
Faces_map& map_f)
: small_arr(small_), big_arr(big),
Faces_map& map_f) :
small_arr(small_), big_arr(big),
big_arr_accessor(big_arr),
map_halfedges(map_h),
map_vertices(map_v),
@ -2135,11 +2124,9 @@ protected:
virtual ~Copy_observer() {}
virtual void before_create_vertex (const Point_2& /* p */)
{}
virtual void before_create_vertex (const Point_2& /* p */) override {}
virtual void after_create_vertex (Vertex_handle v)
{
virtual void after_create_vertex (Vertex_handle v) override {
// should create a new vertex with v->point() inside
Vertex_handle new_v = big_arr_accessor.create_vertex(v->point());
@ -2150,11 +2137,11 @@ protected:
new_vertices.push_back(v);
}
void before_create_boundary_vertex (const X_monotone_curve_2& cv,
virtual void before_create_boundary_vertex(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space in_ps_x,
Arr_parameter_space in_ps_y)
{
override {
boundary_vertex_cv = cv;
boundary_vertex_ind = ind;
ps_x = in_ps_x;
@ -2164,8 +2151,7 @@ protected:
bool is_bounded_impl(Arr_open_side_tag) { return false; }
bool is_bounded_impl(Arr_boundary_side_tag) { return true; }
bool is_bounded()
{
bool is_bounded() {
// This is the case of create boundary vertex.
CGAL_assertion((ps_x != ARR_INTERIOR) || (ps_y != ARR_INTERIOR));
@ -2185,8 +2171,7 @@ protected:
return true;
}
void after_create_boundary_vertex(Vertex_handle v)
{
virtual void after_create_boundary_vertex(Vertex_handle v) override {
CGAL_assertion(big_arr.is_valid());
Vertex_handle new_v =
big_arr_accessor.create_boundary_vertex(boundary_vertex_cv,
@ -2200,16 +2185,15 @@ protected:
map_vertices[v] = new_v;
}
void before_split_fictitious_edge(Halfedge_handle e,
Vertex_handle v)
{
virtual void
before_split_fictitious_edge(Halfedge_handle e, Vertex_handle v) override {
split_fict_v = v;
split_fict_e = e;
}
void after_split_fictitious_edge(Halfedge_handle e1,
Halfedge_handle e2)
{
virtual void
after_split_fictitious_edge(Halfedge_handle e1, Halfedge_handle e2)
override {
// find the corresponding split vertex in big_arr
CGAL_assertion(map_vertices.is_defined(split_fict_v));
Vertex_handle big_v = map_vertices[split_fict_v];
@ -2236,8 +2220,7 @@ protected:
virtual void before_create_edge(const X_monotone_curve_2& /* c */,
Vertex_handle v1,
Vertex_handle v2)
{
Vertex_handle v2) override {
// save state for after_create_edge event
create_edge_v1 = v1;
create_edge_v2 = v2;
@ -2245,9 +2228,7 @@ protected:
is_in_relocate = false;
}
virtual void after_create_edge(Halfedge_handle e)
{
virtual void after_create_edge(Halfedge_handle e) override {
// a new edge e was created in small_arr, we should create a corresponding
// edge in big_arr
CGAL_assertion(map_vertices.is_defined(create_edge_v1));
@ -2261,18 +2242,14 @@ protected:
// if we have 2 new vertices, they must be new.
// if we have only one, we should check which is new
bool v1_is_new = false, v2_is_new = false;
if (new_vertices.size() == 1)
{
if (new_vertices.back() == create_edge_v1)
v1_is_new = true;
else
{
if (new_vertices.size() == 1) {
if (new_vertices.back() == create_edge_v1) v1_is_new = true;
else {
CGAL_assertion(new_vertices.back() == create_edge_v2);
v2_is_new = true;
}
}
if (new_vertices.size() == 2)
{
if (new_vertices.size() == 2) {
v1_is_new = true;
v2_is_new = true;
}
@ -2286,15 +2263,13 @@ protected:
// if an endpoint is not new, but is isolated, we should remove it from
// its face's isolated vertices list, and treat it as new
if (!v1_is_new && big_v1->is_isolated())
{
if (!v1_is_new && big_v1->is_isolated()) {
//Face_handle f = big_v1->face(); //big_arr.incident_face(big_v1);
//big_arr_accessor.find_and_erase_isolated_vertex(f, big_v1);
big_arr_accessor.remove_isolated_vertex_ex(big_v1);
v1_is_new = true;
}
if (!v2_is_new && big_v2->is_isolated())
{
if (! v2_is_new && big_v2->is_isolated()) {
//Face_handle f = big_v2->face(); //big_arr.incident_face(big_v2);
//big_arr_accessor.find_and_erase_isolated_vertex(f, big_v2);
big_arr_accessor.remove_isolated_vertex_ex(big_v2);
@ -2302,8 +2277,7 @@ protected:
}
// now use the approppriate method to insert the new edge
if (v1_is_new && v2_is_new)
{
if (v1_is_new && v2_is_new) {
// if both vertices are new - use the O(1) operation
// _insert_in_face_interior (in the face mapped to by he->face())
CGAL_assertion(map_faces.is_defined(he->face()));
@ -2320,8 +2294,7 @@ protected:
map_halfedges[he] = new_he;
map_halfedges[he->twin()] = new_he->twin();
}
else if (!v1_is_new && !v2_is_new)
{
else if (! v1_is_new && !v2_is_new) {
// if both vertices are old - use _insert_at_vertices
// this is a linear action by the size of the faces involved
// we can get relevant prev halfedges from he
@ -2361,8 +2334,7 @@ protected:
// if a new face was created update its mapping too
// the new face is the incident face of he
if (new_face)
{
if (new_face) {
map_faces[he->face()] = new_he->face();
// save state for move_hole/move_isolated_vertex events
is_in_relocate = true;
@ -2373,16 +2345,14 @@ protected:
CGAL_assertion(map_faces.is_defined(he->face()) &&
map_faces[he->face()] == new_he->face());
}
else
{
else {
// only one vertex is new - use the O(1) operation _insert_from_vertex
// we can get the relevant prev halfedge from e
Halfedge_handle prev = he->prev();
CGAL_assertion(map_halfedges.is_defined(prev));
Halfedge_handle big_prev = map_halfedges[prev];
Halfedge_handle new_he;
if (!v1_is_new)
{
if (!v1_is_new) {
new_he = big_arr_accessor.insert_from_vertex_ex(big_prev,
he->curve(), (HE_COMP_RES(he) == SMALLER ? ARR_LEFT_TO_RIGHT : ARR_RIGHT_TO_LEFT),
big_v2);
@ -2392,8 +2362,7 @@ protected:
map_halfedges[he] = new_he;
map_halfedges[he->twin()] = new_he->twin();
}
else
{
else {
new_he =
big_arr_accessor.insert_from_vertex_ex(big_prev,
he->curve(), (HE_COMP_RES(he->twin()) == SMALLER ? ARR_LEFT_TO_RIGHT : ARR_RIGHT_TO_LEFT),
@ -2411,14 +2380,13 @@ protected:
Vertex_handle v,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */)
{
override {
// save state info for using _split_edge in after event
split_v = v;
split_e = e;
}
virtual void after_split_edge(Halfedge_handle e1,
Halfedge_handle e2)
{
Halfedge_handle e2) override {
// find the corresponding split vertex in big_arr
CGAL_assertion(map_vertices.is_defined(split_v));
Vertex_handle big_v = map_vertices[split_v];
@ -2449,11 +2417,10 @@ protected:
}
virtual void before_add_isolated_vertex(Face_handle f,
Vertex_handle /* v */)
{
saved_face = f;
}
virtual void after_add_isolated_vertex(Vertex_handle v)
Vertex_handle /* v */) override
{ saved_face = f; }
virtual void after_add_isolated_vertex(Vertex_handle v) override
{
// make sure it is the only new vertex right now
CGAL_assertion(new_vertices.size() == 1 &&
@ -2476,15 +2443,14 @@ protected:
virtual void before_move_inner_ccb(Face_handle from_f,
Face_handle to_f,
Ccb_halfedge_circulator )
{
Ccb_halfedge_circulator) override {
// should be used after insert_at_vertices which creates a new face
CGAL_assertion(is_in_relocate);
move_from = from_f;
move_to = to_f;
}
virtual void after_move_inner_ccb(Ccb_halfedge_circulator h)
{
virtual void after_move_inner_ccb(Ccb_halfedge_circulator h) override {
CGAL_assertion(map_faces.is_defined(move_from));
CGAL_assertion(map_faces.is_defined(move_to));
CGAL_assertion(map_halfedges.is_defined(h));
@ -2501,16 +2467,14 @@ protected:
virtual void before_move_isolated_vertex(Face_handle from_f,
Face_handle to_f,
Vertex_handle )
{
Vertex_handle) override {
// should be used after insert_at_vertices which creates a new face
CGAL_assertion(is_in_relocate);
move_from = from_f;
move_to = to_f;
}
virtual void after_move_isolated_vertex(Vertex_handle v)
{
virtual void after_move_isolated_vertex(Vertex_handle v) override {
CGAL_assertion(map_faces.is_defined(move_from));
CGAL_assertion(map_faces.is_defined(move_to));
CGAL_assertion(map_vertices.is_defined(v));
@ -2548,15 +2512,13 @@ protected:
Arr_parameter_space ps_x;
Arr_parameter_space ps_y;
bool is_in_relocate;
};
// A zone visitor for the Minimization Diagram which only inserts
// parts of the curve which are inside a given face
// it also remembers those parts which overlap the boundary of the original
// face
class Copied_face_zone_visitor
{
class Copied_face_zone_visitor {
public:
typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle;
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle;
@ -2822,8 +2784,7 @@ protected:
result_new_he->twin()->set_has_equal_aux_data_in_target_and_face(1, flag);
}
}
else
{
else {
result_new_he->twin()->set_is_equal_aux_data_in_target(0, true);
result_new_he->twin()->set_is_equal_aux_data_in_target(1, true);
result_new_he->twin()->set_has_equal_aux_data_in_target(0, true);
@ -2834,8 +2795,7 @@ protected:
return base_result;
}
else
{
else {
// we don't insert the subcurve, but it might touch a vertex of the
// face's boundary - we need to check it and identify special vertices
if (left_v != Vertex_handle(nullptr) &&
@ -2853,8 +2813,7 @@ protected:
}
}
/*!
* Handle the a subcurve that overlaps a given edge.
/*! Handle the a subcurve that overlaps a given edge.
* \param cv The overlapping subcurve.
* \param he The overlapped halfedge (directed from left to right).
* \param left_v The vertex that corresponds to the left endpoint of cv
@ -2907,7 +2866,6 @@ protected:
}
/*!
* Handle point that lies inside a given face.
* \param p The point.
* \param face The face inside which the point lies.
@ -3161,26 +3119,23 @@ protected:
};
// this minimization diagram observer updates data in new faces created
class New_faces_observer : public Md_observer
{
class New_faces_observer : public Md_observer {
public:
typedef typename Minimization_diagram_2::Face_handle Face_handle;
using Base_aos = typename Minimization_diagram_2::Base_aos;
using Face_handle = typename Base_aos::Face_handle;
New_faces_observer(Minimization_diagram_2& arr) : Md_observer(arr) {}
New_faces_observer(Base_aos& arr) : Md_observer(arr) {}
virtual ~New_faces_observer() {}
virtual void after_split_face(Face_handle org_f,
Face_handle new_f,
bool)
{
virtual void after_split_face(Face_handle org_f, Face_handle new_f, bool)
override {
// update the new face's aux_data from original face
if (org_f->get_aux_is_set(0))
new_f->set_aux_source(0, org_f->get_aux_source(0));
if (org_f->get_aux_is_set(1))
new_f->set_aux_source(1, org_f->get_aux_source(1));
}
};
//! The geometry traits object.

View File

@ -23,6 +23,8 @@ Release date: October 2023
`std::variant`. The support for the old macro `CGAL_ARR_POINT_LOCATION_VERSION`
has been removed.
- Eliminated the error-prone c-type casting that was used to define observers. In general, backward compatibility was maintained; however, the former class template `Arr_observer` was replaced by an alias template. (The former class Arr_observer was renamed to Aos_observer).
#### Envelopes of Surfaces in 3D
- **Breaking change**: Construct_projected_boundary_2 in `EnvelopeTraits_3` is now using `std::variant` instead of `Object`

View File

@ -77,12 +77,15 @@ private:
// An arrangement observer, used to receive notifications of face splits and
// face mergers.
class My_observer : public CGAL::Arr_observer<Arrangement_2> {
class My_observer : public Arrangement_2::Observer {
public:
My_observer(Arrangement_2& arr) : Arr_observer<Arrangement_2>(arr) {}
using Base_aos = typename Arrangement_2::Base_aos;
using Face_handle = typename Base_aos::Face_handle;
My_observer(Base_aos& arr) : Arrangement_2::Observer(arr) {}
virtual void after_split_face(Face_handle f, Face_handle new_f,
bool /* is_hole */)
bool /* is_hole */) override
{ if (f->contained()) new_f->set_contained(true); }
};

View File

@ -21,7 +21,6 @@
#include <memory>
#include <CGAL/boost/iterator/transform_iterator.hpp>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Arr_observer.h>
#include <CGAL/assertions.h>
#include <CGAL/use.h>
@ -86,63 +85,83 @@ private:
};
// Observer to track any changes of the attached arrangement.
class Observer : public Arr_observer<Arrangement_2>
class Observer : public Arrangement_2::Observer
{
typedef Arr_observer<Arrangement_2> Base;
typedef Observer Self;
using Base = typename Arrangement_2::Observer;
using Self = Observer;
public:
using Base_aos = typename Arrangement_2::Base_aos;
using Vertex_handle = typename Base_aos::Vertex_handle;
using Halfedge_handle = typename Base_aos::Halfedge_handle;
using Face_handle = typename Base_aos::Face_handle;
using Ccb_halfedge_circulator = typename Base_aos::Ccb_halfedge_circulator;
bool has_changed;
Observer() : Base(), has_changed(false)
Observer() : Base(), has_changed(false) {}
Observer(const Base_aos& arr) :
Base(const_cast<Base_aos&>(arr)), has_changed(false)
{}
Observer(const Arrangement_2& arr)
: Base(const_cast<Arrangement_2&>(arr)), has_changed(false)
{}
// Aos_observer interface
// Arr_observer interface
virtual void after_attach() override { has_changed = false; }
void after_attach() { has_changed = false; }
void after_global_change() { has_changed = true; }
void after_create_vertex(Vertex_handle) { has_changed = true; }
void after_create_boundary_vertex(Vertex_handle) { has_changed = true; }
void after_create_edge(Halfedge_handle) { has_changed = true; }
void after_modify_vertex(Vertex_handle) { has_changed = true; }
void after_modify_edge(Halfedge_handle) { has_changed = true; }
void after_split_edge(Halfedge_handle, Halfedge_handle) {
has_changed = true; }
void after_split_fictitious_edge(Halfedge_handle, Halfedge_handle) {
has_changed = true; }
void after_split_face(Face_handle, Face_handle, bool) {
has_changed = true; }
void after_split_outer_ccb(Face_handle, Ccb_halfedge_circulator,
Ccb_halfedge_circulator) {
has_changed = true; }
void after_split_inner_ccb(Face_handle, Ccb_halfedge_circulator,
Ccb_halfedge_circulator) {
has_changed = true; }
void after_add_outer_ccb(Ccb_halfedge_circulator) { has_changed = true; }
void after_add_inner_ccb(Ccb_halfedge_circulator) { has_changed = true; }
void after_add_isolated_vertex(Vertex_handle) { has_changed = true; }
void after_merge_edge(Halfedge_handle) { has_changed = true; }
void after_merge_fictitious_edge(Halfedge_handle) { has_changed = true; }
void after_merge_face(Face_handle) { has_changed = true; }
void after_merge_outer_ccb(Face_handle, Ccb_halfedge_circulator) {
has_changed = true; }
void after_merge_inner_ccb(Face_handle, Ccb_halfedge_circulator) {
has_changed = true; }
void after_move_outer_ccb(Ccb_halfedge_circulator) { has_changed = true; }
void after_move_inner_ccb(Ccb_halfedge_circulator) { has_changed = true; }
void after_move_isolated_vertex(Vertex_handle) { has_changed = true; }
void after_remove_vertex() { has_changed = true; }
void after_remove_edge() { has_changed = true; }
void after_remove_outer_ccb(Face_handle) { has_changed = true; }
void after_remove_inner_ccb(Face_handle) { has_changed = true; }
virtual void after_global_change() override { has_changed = true; }
virtual void after_create_vertex(Vertex_handle) override
{ has_changed = true; }
virtual void after_create_boundary_vertex(Vertex_handle) override
{ has_changed = true; }
virtual void after_create_edge(Halfedge_handle) override
{ has_changed = true; }
virtual void after_modify_vertex(Vertex_handle) override
{ has_changed = true; }
virtual void after_modify_edge(Halfedge_handle) override
{ has_changed = true; }
virtual void after_split_edge(Halfedge_handle, Halfedge_handle) override
{ has_changed = true; }
virtual void after_split_fictitious_edge(Halfedge_handle, Halfedge_handle)
override
{ has_changed = true; }
virtual void after_split_face(Face_handle, Face_handle, bool) override
{ has_changed = true; }
virtual void after_split_outer_ccb(Face_handle, Ccb_halfedge_circulator,
Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_split_inner_ccb(Face_handle, Ccb_halfedge_circulator,
Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_add_outer_ccb(Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_add_inner_ccb(Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_add_isolated_vertex(Vertex_handle) override
{ has_changed = true; }
virtual void after_merge_edge(Halfedge_handle) override
{ has_changed = true; }
virtual void after_merge_fictitious_edge(Halfedge_handle) override
{ has_changed = true; }
virtual void after_merge_face(Face_handle) override { has_changed = true; }
virtual void after_merge_outer_ccb(Face_handle, Ccb_halfedge_circulator)
override
{ has_changed = true; }
virtual void after_merge_inner_ccb(Face_handle, Ccb_halfedge_circulator)
override
{ has_changed = true; }
virtual void after_move_outer_ccb(Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_move_inner_ccb(Ccb_halfedge_circulator) override
{ has_changed = true; }
virtual void after_move_isolated_vertex(Vertex_handle) override
{ has_changed = true; }
virtual void after_remove_vertex() override { has_changed = true; }
virtual void after_remove_edge() override { has_changed = true; }
virtual void after_remove_outer_ccb(Face_handle) override
{ has_changed = true; }
virtual void after_remove_inner_ccb(Face_handle) override
{ has_changed = true; }
};