Replace Object

This commit is contained in:
Efi Fogel 2012-02-12 22:52:34 +00:00
parent 9a49162575
commit c9e721511d
4 changed files with 101 additions and 91 deletions

View File

@ -45,7 +45,6 @@ Arr_landmarks_point_location<Arr, Gen>::locate(const Point_2& p) const
// Use the generator and to find the closest landmark to the query point.
result_type lm_location_obj;
const Point_2& landmark_point = lm_gen->closest_landmark(p, lm_location_obj);
CGAL_assertion(! Result().empty(lm_location_obj));
// If the query point and the landmark point are equal, return the landmark.
if (m_traits->equal_2_object()(landmark_point, p))
@ -69,7 +68,6 @@ Arr_landmarks_point_location<Arr, Gen>::locate(const Point_2& p) const
out_obj = _walk_from_face(*fh, landmark_point, p, crossed_edges);
else CGAL_error_msg("lm_location_obj of an unknown type.");
CGAL_assertion(! Result().empty(out_obj));
if (fh = Result().assign<Face_const_handle>(out_obj)) {
// If we reached here, we did not locate the query point in any of the
// holes inside the current face, so we conclude it is contained in this

View File

@ -33,14 +33,14 @@ namespace CGAL {
// Locate the arrangement feature containing the given point.
//
template <class Arrangement>
typename Arr_simple_point_location<Arrangement>::result_type
typename Arr_simple_point_location<Arrangement>::Result_type
Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
{
// Go over the arrangement vertices and check whether one of them equals
// the query point.
typename Traits_adaptor_2::Equal_2 equal = geom_traits->equal_2_object();
typename Traits_adaptor_2::Equal_2 equal = m_geom_traits->equal_2_object();
typename Arrangement::Vertex_const_iterator vit;
for (vit = p_arr->vertices_begin(); vit != p_arr->vertices_end(); ++vit) {
for (vit = m_arr->vertices_begin(); vit != m_arr->vertices_end(); ++vit) {
Vertex_const_handle vh = vit;
if (equal(p, vh->point()))
return result_return(vh);
@ -49,12 +49,12 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// Go over arrangement halfedges and check whether one of them contains
// the query point in its interior.
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range =
geom_traits->is_in_x_range_2_object();
m_geom_traits->is_in_x_range_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 cmp_y_at_x =
geom_traits->compare_y_at_x_2_object();
m_geom_traits->compare_y_at_x_2_object();
typename Arrangement::Edge_const_iterator eit;
for (eit = p_arr->edges_begin(); eit != p_arr->edges_end(); ++eit) {
for (eit = m_arr->edges_begin(); eit != m_arr->edges_end(); ++eit) {
Halfedge_const_handle hh = eit;
if (is_in_x_range(hh->curve(), p) && (cmp_y_at_x(p, hh->curve()) == EQUAL))
return result_return(hh);
@ -63,13 +63,15 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// Shoot a vertical ray from the query point.
// The ray shooting returns either a vertex of a halfedge (or an empty
// object).
result_type obj = _base_vertical_ray_shoot(p, true);
if (Result().empty(obj)) {
Optional_result_type optional_obj = _base_vertical_ray_shoot(p, true);
if (optional_empty(optional_obj)) {
// We should return the unbounded face.
Face_const_handle fh = Face_const_handle(top_traits->initial_face());
Face_const_handle fh = Face_const_handle(m_topol_traits->initial_face());
return result_return(fh);
}
const Result_type& obj = optional_assign(optional_obj);
// In case the ray-shooting returned a vertex, we have to locate the first
// halfedge whose source vertex is v, rotating clockwise around the vertex
// from "6 o'clock", and to return its incident face.
@ -99,7 +101,7 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// given point hits (not inculding isolated vertices).
//
template <class Arrangement>
typename Arr_simple_point_location<Arrangement>::result_type
typename Arr_simple_point_location<Arrangement>::Optional_result_type
Arr_simple_point_location<Arrangement>::
_base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
{
@ -109,18 +111,18 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// Go over all halfedges in the arrangement.
typename Traits_adaptor_2::Is_vertical_2 is_vertical =
geom_traits->is_vertical_2_object();
m_geom_traits->is_vertical_2_object();
typename Traits_adaptor_2::Compare_y_position_2 compare_y_position =
geom_traits->compare_y_position_2_object();
m_geom_traits->compare_y_position_2_object();
typename Traits_adaptor_2::Compare_y_at_x_right_2 compare_y_at_x_right =
geom_traits->compare_y_at_x_right_2_object();
m_geom_traits->compare_y_at_x_right_2_object();
typename Traits_adaptor_2::Compare_y_at_x_left_2 compare_y_at_x_left =
geom_traits->compare_y_at_x_left_2_object();
m_geom_traits->compare_y_at_x_left_2_object();
typename Dcel::Edge_const_iterator eit =
top_traits->dcel().edges_begin();
m_topol_traits->dcel().edges_begin();
typename Dcel::Edge_const_iterator e_end =
top_traits->dcel().edges_end();
m_topol_traits->dcel().edges_end();
const typename Dcel::Halfedge* he; // The current edge.
const typename Dcel::Vertex* vs; // The current edge source
const typename Dcel::Vertex* vt; // The current edge target.
@ -140,18 +142,17 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// Determine whether p is in the x-range of the curve and above or below it
// (according to the direction of the shoot).
res_s = top_traits->compare_x(p, vs);
res_s = m_topol_traits->compare_x(p, vs);
in_x_range = (res_s == EQUAL) ?
true :
(((res_s == SMALLER && he->direction() == ARR_LEFT_TO_RIGHT) ||
(res_s == LARGER && he->direction() == ARR_RIGHT_TO_LEFT)) ?
false : (res_s != top_traits->compare_x(p, vt)));
in_x_range = (res_s == EQUAL) ? true :
((((res_s == SMALLER) && (he->direction() == ARR_LEFT_TO_RIGHT)) ||
((res_s == LARGER) && (he->direction() == ARR_RIGHT_TO_LEFT))) ? false :
(res_s != m_topol_traits->compare_x(p, vt)));
if (in_x_range)
res = top_traits->compare_y_at_x(p, he);
res = m_topol_traits->compare_y_at_x(p, he);
if (in_x_range && res == point_above_under) {
if (in_x_range && (res == point_above_under)) {
if (closest_he == NULL) {
// If no other x-monotone curve containing p in its x-range has been
// found yet, take the current one as the vertically closest to p.
@ -166,8 +167,8 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// in their interiors). Observe that if such a common vertex exists,
// it is certainly not a vertex at infinity, therefore it is
// associated with a valid point.
if ((cl_vs == vs && closest_he->direction() == eit->direction()) ||
(cl_vs == vt && closest_he->direction() != eit->direction()))
if (((cl_vs == vs) && (closest_he->direction() == eit->direction())) ||
((cl_vs == vt) && (closest_he->direction() != eit->direction())))
{
CGAL_assertion(! cl_vs->has_null_point());
@ -198,8 +199,7 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// in their x-range (both contain p), just compare their positions.
// Note that in this case one of the edges may be fictitious, so we
// preform the comparsion symbolically in this case.
y_res = (closest_he->has_null_curve()) ?
curve_above_under :
y_res = (closest_he->has_null_curve()) ? curve_above_under :
((eit->has_null_curve()) ? point_above_under :
compare_y_position(closest_he->curve(), eit->curve()));
}
@ -214,16 +214,16 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
}
}
if (in_x_range && res == EQUAL &&
if ((in_x_range && res == EQUAL) &&
! eit->has_null_curve() && is_vertical(eit->curve()))
{
// Check if the query point is one of the end-vertices of the vertical
// edge.
Comparison_result res1 = top_traits->compare_xy(p, vs);
Comparison_result res2 = top_traits->compare_xy(p, vt);
Comparison_result res1 = m_topol_traits->compare_xy(p, vs);
Comparison_result res2 = m_topol_traits->compare_xy(p, vt);
if (! ((res1 == EQUAL && res2 == curve_above_under) ||
(res1 == curve_above_under && res2 == EQUAL)))
if (! (((res1 == EQUAL) && (res2 == curve_above_under)) ||
((res1 == curve_above_under) && (res2 == EQUAL))))
{
// The vertical ray overlaps an existing vertical edge containing p.
// In this case simply return this edge.
@ -248,20 +248,16 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// as the query point, return this vertex.
if (! is_vertical(closest_he->curve())) {
if (! cl_vs->has_null_point() &&
geom_traits->compare_x_2_object()(cl_vs->point(), p) == EQUAL)
{
m_geom_traits->compare_x_2_object()(cl_vs->point(), p) == EQUAL)
return result_return(Vertex_const_handle(cl_vs));
}
else if (! cl_vt->has_null_point() &&
geom_traits->compare_x_2_object()(cl_vt->point(), p) == EQUAL)
{
m_geom_traits->compare_x_2_object()(cl_vt->point(), p) == EQUAL)
return result_return(Vertex_const_handle(cl_vt));
}
}
else {
CGAL_assertion_code(
Comparison_result res1 = top_traits->compare_xy(p, cl_vs);
Comparison_result res2 = top_traits->compare_xy(p, cl_vt));
Comparison_result res1 = m_topol_traits->compare_xy(p, cl_vs);
Comparison_result res2 = m_topol_traits->compare_xy(p, cl_vt));
CGAL_assertion(res1 == res2);
CGAL_assertion(res1 == point_above_under);
@ -281,20 +277,21 @@ _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const
// given point hits, considering isolated vertices.
//
template <typename Arrangement>
typename Arr_simple_point_location<Arrangement>::result_type
typename Arr_simple_point_location<Arrangement>::Result_type
Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
bool shoot_up) const
{
// Locate the arrangement feature which a vertical ray emanating from the
// given point hits, when not considering the isolated vertices.
// This feature may not exist, or be either a vertex of a halfedge.
result_type obj = _base_vertical_ray_shoot(p, shoot_up);
Optional_result_type optional_obj = _base_vertical_ray_shoot(p, shoot_up);
bool found_vertex = false;
bool found_halfedge = false;
Vertex_const_handle closest_v;
Halfedge_const_handle closest_he;
if (! Result().empty(obj)) {
if (! optional_empty(optional_obj)) {
const Result_type& obj = optional_assign(optional_obj);
const Vertex_const_handle* p_vh = Result().assign<Vertex_const_handle>(obj);
if (p_vh) {
found_vertex = true;
@ -314,15 +311,15 @@ Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
// Go over all isolated vertices in the arrangement.
typename Traits_adaptor_2::Compare_x_2 compare_x =
geom_traits->compare_x_2_object();
m_geom_traits->compare_x_2_object();
typename Traits_adaptor_2::Compare_xy_2 compare_xy =
geom_traits->compare_xy_2_object();
m_geom_traits->compare_xy_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 compare_y_at_x =
geom_traits->compare_y_at_x_2_object();
m_geom_traits->compare_y_at_x_2_object();
Vertex_const_handle vh;
typename Arrangement::Vertex_const_iterator vit;
for (vit = p_arr->vertices_begin(); vit != p_arr->vertices_end(); ++vit) {
for (vit = m_arr->vertices_begin(); vit != m_arr->vertices_end(); ++vit) {
vh = vit;
if (! vh->is_isolated())
continue;
@ -372,7 +369,7 @@ Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
}
// If we have no halfedge above, return the initial face.
Face_const_handle uf = Face_const_handle(top_traits->initial_face());
Face_const_handle uf = Face_const_handle(m_topol_traits->initial_face());
return result_return(uf);
}
@ -388,9 +385,9 @@ _first_around_vertex(Vertex_const_handle v) const
// Travrse the incident halfedges of the current vertex and locate the
// lowest one to its left and the topmost to its right.
typename Traits_adaptor_2::Compare_y_at_x_right_2 compare_y_at_x_right =
geom_traits->compare_y_at_x_right_2_object();
m_geom_traits->compare_y_at_x_right_2_object();
typename Traits_adaptor_2::Compare_y_at_x_left_2 compare_y_at_x_left =
geom_traits->compare_y_at_x_left_2_object();
m_geom_traits->compare_y_at_x_left_2_object();
const Halfedge_const_handle invalid_handle;
Halfedge_const_handle lowest_left;

View File

@ -20,20 +20,19 @@
#ifndef CGAL_ARR_POINT_LOCATION_RESULT_H
#define CGAL_ARR_POINT_LOCATION_RESULT_H
// The macro CGAL_POINT_LOCATION_VERSION controls which version of the
// The macro CGAL_ARR_POINT_LOCATION_VERSION controls which version of the
// point location is used. Currently two values are supported:
// 1. Point location with CGAL::Object
// 2. Point location with boost::optional<boost::variant<...> >
// The default value is 2.
#if !defined(CGAL_POINT_LOCATION_VERSION)
#define CGAL_POINT_LOCATION_VERSION 2
#if !defined(CGAL_ARR_POINT_LOCATION_VERSION)
#define CGAL_ARR_POINT_LOCATION_VERSION 2
#endif
#include <CGAL/Object.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
namespace CGAL {
@ -45,13 +44,12 @@ struct Arr_point_location_result {
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
#if CGAL_POINT_LOCATION_VERSION < 2
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
typedef CGAL::Object Type;
#else
typedef typename boost::variant<Vertex_const_handle,
Halfedge_const_handle,
Face_const_handle> Variant_type;
typedef typename boost::optional<Variant_type> Type;
Face_const_handle> Type;
#endif
typedef Type type;
@ -62,15 +60,12 @@ struct Arr_point_location_result {
// In theory a one parameter variant could be returned, but this _could_
// lead to conversion overhead, and so we rather go for the real type.
// Overloads for empty returns are also provided.
#if CGAL_POINT_LOCATION_VERSION < 2
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
template<typename T>
inline CGAL::Object operator()(T t) const { return CGAL::make_object(t); }
inline CGAL::Object operator()() const { return CGAL::Object(); }
template<typename T>
inline bool empty(T t) const { return t.empty(); }
template<typename T>
T* assign(CGAL::Object obj) const { return CGAL::object_cast<T>(&obj); }
#else
@ -80,11 +75,8 @@ struct Arr_point_location_result {
inline Type operator()() const { return Type(); }
template<typename T>
inline bool empty(T t) const { return (t == NULL); }
template<typename T>
T* assign(Type obj) const { return boost::get<T>(&(*obj)); }
#endif // CGAL_POINT_LOCATION_VERSION < 2
T* assign(Type obj) const { return boost::get<T>(&obj); }
#endif // CGAL_ARR_POINT_LOCATION_VERSION < 2
};
} //namespace CGAL

View File

@ -29,6 +29,8 @@
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <boost/optional.hpp>
namespace CGAL {
/*! \class
@ -58,14 +60,34 @@ public:
typedef Result_type result_type;
protected:
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
typedef Result_type Optional_result_type;
#else
typedef typename boost::optional<Result_type> Optional_result_type;
#endif
typedef typename Topology_traits::Dcel Dcel;
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
// Data members:
const Arrangement_2* p_arr; // The associated arrangement.
const Traits_adaptor_2* geom_traits; // Its associated geometry traits.
const Topology_traits* top_traits; // Its associated topology traits.
const Arrangement_2* m_arr; // The associated arrangement.
const Traits_adaptor_2* m_geom_traits; // Its associated geometry traits.
const Topology_traits* m_topol_traits; // Its associated topology traits.
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
template<typename T>
inline bool optional_empty(T t) const { return t.empty(); }
template<typename T>
inline const Result_type& optional_assign(T t) const { return t; }
#else
template<typename T>
inline bool optional_empty(T t) const { return (!t); }
template<typename T>
inline const Result_type& optional_assign(T t) const { return *t; }
#endif
template<typename T>
Result_type result_return(T t) const { return Result()(t); }
inline Result_type result_return() const { return Result()(); }
@ -73,35 +95,35 @@ protected:
public:
/*! Default constructor. */
Arr_simple_point_location() :
p_arr(NULL),
geom_traits(NULL),
top_traits(NULL)
m_arr(NULL),
m_geom_traits(NULL),
m_topol_traits(NULL)
{}
/*! Constructor given an arrangement. */
Arr_simple_point_location(const Arrangement_2& arr) :
p_arr(&arr)
m_arr(&arr)
{
geom_traits =
static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits());
top_traits = p_arr->topology_traits();
m_geom_traits =
static_cast<const Traits_adaptor_2*>(m_arr->geometry_traits());
m_topol_traits = m_arr->topology_traits();
}
/*! Attach an arrangement object. */
void attach(const Arrangement_2& arr)
{
p_arr = &arr;
geom_traits =
static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits());
top_traits = p_arr->topology_traits();
m_arr = &arr;
m_geom_traits =
static_cast<const Traits_adaptor_2*>(m_arr->geometry_traits());
m_topol_traits = m_arr->topology_traits();
}
/*! Detach from the current arrangement object. */
void detach()
{
p_arr = NULL;
geom_traits = NULL;
top_traits = NULL;
m_arr = NULL;
m_geom_traits = NULL;
m_topol_traits = NULL;
}
/*!
@ -111,7 +133,7 @@ public:
* query point. This object is either a Face_const_handle or a
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type locate(const Point_2& p) const;
Result_type locate(const Point_2& p) const;
/*!
* Locate the arrangement feature which a upward vertical ray emanating from
@ -121,7 +143,7 @@ public:
* This object is either an empty object or a
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type ray_shoot_up(const Point_2& p) const
Result_type ray_shoot_up(const Point_2& p) const
{ return (_vertical_ray_shoot(p, true)); }
/*!
@ -132,7 +154,7 @@ public:
* This object is either an empty object or a
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type ray_shoot_down(const Point_2& p) const
Result_type ray_shoot_down(const Point_2& p) const
{ return (_vertical_ray_shoot(p, false)); }
protected:
@ -145,7 +167,8 @@ protected:
* This object is either a Halfedge_const_handle,
* a Vertex_const_handle or an empty object.
*/
result_type _base_vertical_ray_shoot(const Point_2& p, bool shoot_up) const;
Optional_result_type _base_vertical_ray_shoot(const Point_2& p,
bool shoot_up) const;
/*!
* Locate the arrangement feature which a vertical ray emanating from the
@ -156,7 +179,7 @@ protected:
* This object is either a Halfedge_const_handle,
* a Vertex_const_handle or an empty object.
*/
result_type _vertical_ray_shoot(const Point_2& p, bool shoot_up) const;
Result_type _vertical_ray_shoot(const Point_2& p, bool shoot_up) const;
/*!
* Find the first halfedge with a given source vertex, when going clockwise