Eliminated the error-prone c-style casting of the arrangement that occurs when using observers; renamed Arr_observer => Aos_observer, and introduced Arr_observer for backward compatibility.

This commit is contained in:
Efi Fogel 2023-12-12 02:54:19 +02:00
parent 5544ff4893
commit 92e2a7da2d
14 changed files with 1054 additions and 1000 deletions

View File

@ -5703,22 +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 that observes changes that an arrangement object of
type `Arrangement` undergoes must be of a type derived from
`Arrangement::Observer`. The observer object stores a pointer to the
observed 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.
`Arrangement::Observer` is an alias to
`Arr_observer<CGAL::Arrangement_on_surface_2<>>`, where
`CGAL::Arrangement_on_surface_2<>` is the type of the arrangement
object or its base type. It serves as a base type 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
`Arrangement_on_surface_2`. The set of functions can be divided into
three categories, as follows:
<OL>
@ -5784,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
@ -5801,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
@ -5811,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,409 @@
namespace CGAL {
/*! \ingroup PkgArrangementOnSurface2Ref
*
* \anchor arr_refarr_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;
/*! */
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. */
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 `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 Aos_observer */
} /* end namespace CGAL */

View File

@ -1,409 +1,33 @@
// Copyright (c) 2023 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): 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>
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()`).
*/
template< typename Arrangement >
class Arr_observer {
public:
template <typename Arrangement_>
using Arr_observer = typename Arrangement_::Observer;
/// \name Types
/// @{
} // namespace CGAL
/*! the type of the associated arrangement. */
typedef unspecified_type Arrangement_2;
#include <CGAL/enable_warnings.h>
/*! 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 */
#endif

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

@ -3,6 +3,7 @@
#include <CGAL/basic.h>
#include <CGAL/Arr_extended_dcel.h>
#include <CGAL/Arr_observer.h>
#include "arr_exact_construction_segments.h"
@ -11,13 +12,13 @@ using Ex_arrangement = CGAL::Arrangement_2<Traits, Dcel>;
// An arrangement observer, used to receive notifications of face splits and
// to update the indices of the newly created faces.
class Face_index_observer : public Ex_arrangement::Observer {
class Face_index_observer : public CGAL::Arr_observer<Ex_arrangement> {
private:
size_t n_faces; // the current number of faces
public:
Face_index_observer(Ex_arrangement& arr) :
Ex_arrangement::Observer(arr),
CGAL::Arr_observer<Ex_arrangement>(arr),
n_faces(0)
{
CGAL_precondition(arr.is_empty());

View File

@ -2,14 +2,15 @@
// Using a simple arrangement observer.
#include <CGAL/basic.h>
#include <CGAL/Arr_observer.h>
#include "arr_exact_construction_segments.h"
#include "arr_print.h"
// An observer that receives notifications of face splits and face mergers.
class My_observer : public Arrangement::Observer {
class My_observer : public CGAL::Arr_observer<Arrangement> {
public:
My_observer(Arrangement& arr) : Arrangement::Observer(arr) {}
My_observer(Arrangement& arr) : CGAL::Arr_observer<Arrangement>(arr) {}
virtual void before_split_face(Face_handle, Halfedge_handle e) {
std::cout << "-> The insertion of : [ " << e->curve()

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,573 @@
// 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 (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 */) {}
//@}
};
} //namespace CGAL
#include <CGAL/enable_warnings.h>
#endif

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,565 +8,25 @@
// 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;
using Arr_observer = typename Arrangement_::Observer;
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 */) {}
//@}
};
} //namespace CGAL
} // namespace CGAL
#include <CGAL/enable_warnings.h>

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>

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,10 +109,10 @@ public:
typedef typename Topology_traits::Dcel Dcel;
typedef typename Dcel::Size Size;
typedef Arr_observer<Self> Observer;
typedef Aos_observer<Self> Observer;
protected:
friend class Arr_observer<Self>;
friend class Aos_observer<Self>;
friend class Arr_accessor<Self>;
// Internal DCEL types:

View File

@ -272,7 +272,7 @@ 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:
typedef typename Base_arr_2::Halfedge_handle Halfedge_handle;

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>

View File

@ -102,7 +102,7 @@ private:
: Base(const_cast<Arrangement_2&>(arr)), has_changed(false)
{}
// Arr_observer interface
// Aos_observer interface
void after_attach() { has_changed = false; }