cgal/Envelope_3/include/CGAL/Arrangement_2_incremental_i...

192 lines
6.3 KiB
C++

// Copyright (c) 2005 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
#ifndef CGAL_ARRANGEMENT_2_INCREMENTAL_INSERT_H
#define CGAL_ARRANGEMENT_2_INCREMENTAL_INSERT_H
/*! \file
* Global incremental insertion function for the Arrangement_2 class
* with Zone Visitor parameter.
*/
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_accessor.h>
#ifdef CGAL_ENVELOPE_USE_IMPROVED_ZONE
#include <CGAL/Envelope_arrangement_zone_2.h>
#else
#include <CGAL/Arrangement_zone_2.h>
#endif
#include <CGAL/Arrangement_2/Arr_inc_insertion_zone_visitor.h>
#include <list>
#include <map>
CGAL_BEGIN_NAMESPACE
//-----------------------------------------------------------------------------
// Insert a curve into the arrangement (incremental insertion).
// The inserted x-monotone curve may intersect the existing arrangement.
// Use the given zone visitor.
//
template <class Traits, class Dcel, class PointLocation, class ZoneVisitor>
void insert_curve (Arrangement_2<Traits,Dcel>& arr,
const typename Traits::Curve_2& c,
const PointLocation& pl,
ZoneVisitor& visitor)
{
// Obtain an arrangement accessor.
typedef Arrangement_2<Traits,Dcel> Arrangement_2;
Arr_accessor<Arrangement_2> arr_access (arr);
#ifdef CGAL_ENVELOPE_USE_IMPROVED_ZONE
Envelope_arrangement_zone_2<Arrangement_2, ZoneVisitor>
arr_zone (arr, &visitor);
#else
Arrangement_zone_2<Arrangement_2, ZoneVisitor> arr_zone (arr, &visitor);
#endif
// Break the input curve into x-monotone subcurves and isolated points.
typedef Arr_traits_adaptor_2<Traits> Traits_wrapper_2;
Traits_wrapper_2 *traits =
static_cast<Traits_wrapper_2*>(arr.get_traits());
std::list<Object> x_objects;
std::list<Object>::const_iterator obj_iter;
typename Traits::X_monotone_curve_2 x_curve;
typename Traits::Point_2 iso_p;
Object obj;
bool assign_success;
traits->make_x_monotone_2_object() (c,
std::back_inserter (x_objects));
// Insert each x-monotone curve into the arrangement.
for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter)
{
// Act according to the type of the current object.
if (assign (x_curve, *obj_iter))
{
// Inserting an x-monotone curve:
// Initialize the zone-computation object with the given curve.
arr_zone.init (x_curve, pl);
// Notify the arrangement observers that a global operation is about to
// take place.
arr_access.notify_before_global_change();
// Insert the current x-monotone curve into the arrangement.
arr_zone.compute_zone();
// Notify the arrangement observers that the global operation has been
// completed.
arr_access.notify_after_global_change();
}
else
{
assign_success = assign (iso_p, *obj_iter);
CGAL_assertion (assign_success);
if (! assign_success)
continue;
// Inserting a point into the arrangement:
//insert_vertex (arr, iso_p, pl);
// we use the version with the visitor
insert_point(arr, iso_p, pl, visitor);
}
}
return;
}
//-----------------------------------------------------------------------------
// Insert a vertex that corresponds to a given point into the arrangement.
// The inserted point may lie on any existing arrangement feature.
// Use the given visitor to actually change the arrangement.
// The visitor's methods should return the Vertex_handle of the new vertex,
// if one was created, or an invalid handle, if a vertex wasn't created.
//
template <class Traits, class Dcel, class PointLocation, class Visitor>
typename Arrangement_2<Traits,Dcel>::Vertex_handle
insert_point (Arrangement_2<Traits,Dcel>& arr,
const typename Traits::Point_2& p,
const PointLocation& pl,
Visitor& visitor)
{
// Obtain an arrangement accessor.
typedef Arrangement_2<Traits,Dcel> Arrangement_2;
// Act according to the type of arrangement feature that contains the point.
const typename Arrangement_2::Face_const_handle *fh;
const typename Arrangement_2::Halfedge_const_handle *hh;
const typename Arrangement_2::Vertex_const_handle *vh;
typename Arrangement_2::Vertex_handle vh_for_p;
Arr_accessor<Arrangement_2> arr_access (arr);
// Locate the given point in the arrangement.
CGAL::Object obj = pl.locate (p);
// Notify the arrangement observers that a global operation is about to
// take place.
arr_access.notify_before_global_change();
visitor.init(&arr);
if ((fh = object_cast<typename Arrangement_2::Face_const_handle>(&obj))
!= NULL)
{
vh_for_p = visitor.found_point_in_face(p, arr.non_const_handle (*fh));
}
else if ((hh =
object_cast<typename Arrangement_2::Halfedge_const_handle>(&obj))
!= NULL)
{
vh_for_p = visitor.found_point_on_edge(p , arr.non_const_handle (*hh));
}
else
{
// In this case p lies on an existing vertex, so we just update this
// vertex.
vh = object_cast<typename Arrangement_2::Vertex_const_handle>(&obj);
CGAL_assertion (vh != NULL);
vh_for_p = visitor.found_point_on_vertex(p, arr.non_const_handle (*vh));
}
// Notify the arrangement observers that the global operation has been
// completed.
arr_access.notify_after_global_change();
// Return a handle for the vertex associated with p.
return (vh_for_p);
}
CGAL_END_NAMESPACE
#endif