mirror of https://github.com/CGAL/cgal
1969 lines
84 KiB
C++
1969 lines
84 KiB
C++
// Copyright (c) 2001-2004 ENS of Paris (France).
|
||
// 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) : Pierre Angelier, Michel Pocchiola
|
||
|
||
#ifndef CGAL_VISIBILITY_COMPLEX_ANTICHAIN_H
|
||
#define CGAL_VISIBILITY_COMPLEX_ANTICHAIN_H
|
||
|
||
#include <CGAL/basic.h>
|
||
#include <CGAL/Visibility_complex_function_objects.h>
|
||
#include <CGAL/In_place_list.h>
|
||
#include <CGAL/Visibility_complex_items.h>
|
||
#include <CGAL/Visibility_complex_flip_traits.h>
|
||
#include <CGAL/Visibility_complex_antichain_iterators.h>
|
||
#include <CGAL/Visibility_complex_ccw_cw_traits.h>
|
||
#include <CGAL/Visibility_complex_function_objects.h>
|
||
#include <CGAL/Visibility_complex_sweep_iterator.h>
|
||
|
||
#include <queue>
|
||
#include <list>
|
||
#include <set>
|
||
|
||
CGAL_BEGIN_NAMESPACE
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class Vertex_base>
|
||
class Visibility_complex_vertex
|
||
: public Vertex_base,
|
||
public In_place_list_base< Visibility_complex_vertex<Vertex_base> >
|
||
{
|
||
public:
|
||
typedef Visibility_complex_vertex< Vertex_base> Self;
|
||
typedef typename Vertex_base::Vertex_handle Vertex_handle;
|
||
typedef typename Vertex_base::Edge_handle Edge_handle;
|
||
typedef typename Vertex_base::Disk_handle Disk_handle;
|
||
typedef typename Vertex_base::Bitangent_2 Bitangent_2;
|
||
typedef typename Vertex_base::Type Type;
|
||
|
||
Visibility_complex_vertex() {}
|
||
Visibility_complex_vertex(Type t , Disk_handle start ,
|
||
Disk_handle finish)
|
||
: Vertex_base(t,start,finish) {}
|
||
Visibility_complex_vertex(Edge_handle start , Edge_handle finish)
|
||
: Vertex_base(start,finish) {}
|
||
Visibility_complex_vertex(const Bitangent_2& b)
|
||
: Vertex_base(b) {}
|
||
Visibility_complex_vertex( const Vertex_base& v) // down cast
|
||
: Vertex_base(v) {}
|
||
Self& operator=( const Self& v) {
|
||
this->Vertex_base::operator=(v);
|
||
return *this;
|
||
}
|
||
void set_color(bool b) { _color = b; }
|
||
bool color() const { return _color; }
|
||
private:
|
||
bool _color;
|
||
};
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template <class Edge_base>
|
||
class Visibility_complex_edge
|
||
: public Edge_base,
|
||
public In_place_list_base< Visibility_complex_edge<Edge_base> >
|
||
{
|
||
public:
|
||
typedef Visibility_complex_edge<Edge_base> Self;
|
||
typedef typename Edge_base::Vertex_handle Vertex_handle;
|
||
typedef typename Edge_base::Disk_handle Disk_handle;
|
||
|
||
Visibility_complex_edge() {}
|
||
Visibility_complex_edge(bool s, Disk_handle p)
|
||
: Edge_base(s,p) {}
|
||
Visibility_complex_edge(Vertex_handle v0 , Vertex_handle v1 ,
|
||
Disk_handle p)
|
||
: Edge_base(v0,v1,p) {}
|
||
Visibility_complex_edge( const Edge_base& h)
|
||
: Edge_base(h) {}
|
||
Self& operator=( const Self& e) {
|
||
this->Edge_base::operator=(e);
|
||
return *this;
|
||
}
|
||
};
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class Face_base>
|
||
class Visibility_complex_face
|
||
: public Face_base, public In_place_list_base<
|
||
Visibility_complex_face< Face_base> > {
|
||
public:
|
||
typedef Visibility_complex_face< Face_base> Self;
|
||
Visibility_complex_face() {}
|
||
Visibility_complex_face(const Face_base& f) : Face_base(f) {}
|
||
Self& operator=( const Self& f) {
|
||
this->Face_base::operator=(f);
|
||
return *this;
|
||
}
|
||
};
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr ,
|
||
class It = Visibility_complex_items ,
|
||
class Flip = Visibility_complex_flip_traits >
|
||
class Visibility_complex_antichain
|
||
: public In_place_list< Visibility_complex_edge<typename It::template Edge_wrapper< Visibility_complex_antichain<_Gtr, It, Flip> >::Edge>, false>
|
||
{
|
||
public:
|
||
// -------------------------------------------------------------------------
|
||
typedef _Gtr Gt;
|
||
typedef typename _Gtr::Disk Disk;
|
||
typedef typename _Gtr::Point_2 Point_2;
|
||
typedef typename _Gtr::Bitangent_2 Bitangent_2;
|
||
typedef Bitangent_2 BT;
|
||
typedef typename BT::Disk_handle Disk_handle;
|
||
// -------------------------------------------------------------------------
|
||
typedef Visibility_complex_antichain<_Gtr,It,Flip> Self;
|
||
typedef Visibility_complex_antichain<_Gtr,It,Flip> Antichain;
|
||
// -------------------------------------------------------------------------
|
||
typedef Visibility_complex_left_ccw_traits<Self> Left_ccw_traits;
|
||
typedef Visibility_complex_right_ccw_traits<Self> Right_ccw_traits;
|
||
typedef Visibility_complex_left_cw_traits<Self> Left_cw_traits;
|
||
typedef Visibility_complex_right_cw_traits<Self> Right_cw_traits;
|
||
typedef Right_ccw_traits Ccw_traits;
|
||
typedef Right_cw_traits Cw_traits;
|
||
// -------------------------------------------------------------------------
|
||
/*
|
||
typedef typename Visibility_complex_backward_flip_traits:: Flip_wrapper<Self>
|
||
Flip_wrapper;
|
||
*/
|
||
typedef typename Flip::template Flip_wrapper<Self> Flip_wrapper;
|
||
typedef Flip_wrapper FW;
|
||
typedef typename FW::Flip_traits Flip_traits;
|
||
// -------------------------------------------------------------------------
|
||
typedef typename It::template Vertex_wrapper<Self> Vertex_wrapper;
|
||
typedef typename Vertex_wrapper::Vertex Vertex_base;
|
||
typedef Visibility_complex_vertex< Vertex_base> Vertex;
|
||
typedef Vertex* Vertex_handle;
|
||
typedef typename In_place_list<Vertex,false>::iterator Minimals_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef typename It::template Edge_wrapper<Self> Edge_wrapper;
|
||
typedef typename Edge_wrapper::Edge Edge_base;
|
||
typedef Visibility_complex_edge< Edge_base> Edge;
|
||
typedef Edge* Edge_handle;
|
||
typedef In_place_list<Edge,false> Base;
|
||
typedef typename In_place_list<Edge,false>::iterator Edge_iterator;
|
||
typedef typename In_place_list<Edge,false>::reverse_iterator Edge_reverse_iterator;
|
||
typedef typename In_place_list<Edge,false>::const_iterator Edge_const_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef typename It::template Face_wrapper<Self> Face_wrapper;
|
||
typedef typename Face_wrapper::Face Face_base;
|
||
typedef Visibility_complex_face< Face_base> Face;
|
||
typedef Face* Face_handle;
|
||
typedef Vc_antichain_face_iterator<Self,Face,
|
||
Face&,Face_handle> Face_iterator;
|
||
typedef Vc_antichain_face_iterator<Self,Face,
|
||
const Face&,const Face_handle>
|
||
Face_const_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef Vc_antichain_vertex_iterator<Self,Vertex, Vertex&,
|
||
Vertex_handle, typename Ccw_traits::Sup>
|
||
Vertex_iterator;
|
||
typedef Vc_antichain_vertex_iterator<Self,Vertex, const Vertex&,
|
||
const Vertex_handle,
|
||
typename Ccw_traits::Sup>
|
||
Vertex_const_iterator;
|
||
typedef Vc_antichain_vertex_iterator<Self,Vertex, Vertex&,
|
||
Vertex_handle, typename Cw_traits::Sup>
|
||
Vertex_cw_iterator;
|
||
typedef Vc_antichain_vertex_iterator<Self,Vertex, const Vertex&,
|
||
const Vertex_handle,
|
||
typename Cw_traits::Sup>
|
||
Vertex_cw_const_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef Visibility_complex_linear_sweep_iterator<Antichain,Vertex,
|
||
Vertex&,Vertex_handle,
|
||
typename Gt::Is_upward_directed>
|
||
Linear_sweep_iterator;
|
||
typedef Visibility_complex_linear_sweep_iterator<Antichain,Vertex,
|
||
const Vertex&,const Vertex_handle,
|
||
typename Gt::Is_upward_directed>
|
||
Linear_sweep_const_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef Visibility_complex_sweep_iterator<Antichain,Vertex,
|
||
Vertex&,Vertex_handle>
|
||
Sweep_iterator;
|
||
typedef Visibility_complex_sweep_iterator<Antichain,Vertex,
|
||
const Vertex&,const Vertex_handle>
|
||
Sweep_const_iterator;
|
||
// -------------------------------------------------------------------------
|
||
typedef typename BT::Type_util Type_util;
|
||
// -------------------------------------------------------------------------
|
||
using Base::destroy;
|
||
using Base::begin;
|
||
using Base::end;
|
||
using Base::rbegin;
|
||
using Base::rend;
|
||
|
||
|
||
private:
|
||
bool _valid;
|
||
bool _straight_sweep;
|
||
bool _linear_space;
|
||
Face_handle _infinite_face;
|
||
In_place_list<Vertex,false> _minimals_ccw;
|
||
In_place_list<Vertex,false> _minimals_cw;
|
||
|
||
#ifdef DEBUG
|
||
std::map<long,int> Key;
|
||
#endif
|
||
|
||
public :
|
||
|
||
// -------------------------------------------------------------------------
|
||
Visibility_complex_antichain()
|
||
: _valid(false) , _straight_sweep(false) , _linear_space(true)
|
||
{ }
|
||
template < class InputIterator ,class ConstraintIt >
|
||
Visibility_complex_antichain(InputIterator first, InputIterator last,
|
||
ConstraintIt firstc,ConstraintIt lastc);
|
||
~Visibility_complex_antichain() { destroy(); }
|
||
// -------------------------------------------------------------------------
|
||
// Options when sweeping
|
||
bool is_valid() const { return _valid; }
|
||
bool is_straight() const { return _straight_sweep; }
|
||
void make_straight() { _straight_sweep = true; }
|
||
bool linear_space() const { return _linear_space; }
|
||
void set_linear_space(bool b) { _linear_space = b; }
|
||
// -------------------------------------------------------------------------
|
||
// Identifying convex-hull vertices
|
||
Face_handle infinite_face() const { return _infinite_face; }
|
||
void create_infinite_face() { _infinite_face = new Face; }
|
||
bool is_on_convex_hull(Vertex_handle v) const;
|
||
// -------------------------------------------------------------------------
|
||
// Iterator pairs for trversing the sink of the faces of the antichain
|
||
// These vertices form the Greedy pseudo-triangulation
|
||
Vertex_iterator vertices_begin()
|
||
{ return Vertex_iterator(this,begin()); }
|
||
Vertex_const_iterator vertices_begin() const
|
||
{ return Vertex_const_iterator(this,begin()); }
|
||
Vertex_iterator vertices_end()
|
||
{ return Vertex_iterator(this,end()); }
|
||
Vertex_const_iterator vertices_end() const
|
||
{ return Vertex_const_iterator(this,end()); }
|
||
// -------------------------------------------------------------------------
|
||
// Iterator pairs for trversing the sources of the faces of the antichain
|
||
// These vertices form the dual Greedy pseudo-triangulation
|
||
Vertex_cw_iterator cw_vertices_begin()
|
||
{ return Vertex_cw_iterator(this,begin()); }
|
||
Vertex_cw_const_iterator cw_vertices_begin() const
|
||
{ return Vertex_cw_const_iterator(this,begin()); }
|
||
Vertex_cw_iterator cw_vertices_end()
|
||
{ return Vertex_cw_iterator(this,end()); }
|
||
Vertex_cw_const_iterator cw_vertices_end() const
|
||
{ return Vertex_cw_const_iterator(this,end()); }
|
||
// -------------------------------------------------------------------------
|
||
Edge_iterator edges_begin() { return begin(); }
|
||
Edge_const_iterator edges_begin() const { return begin(); }
|
||
Edge_iterator edges_end() { return end(); }
|
||
Edge_const_iterator edges_end() const { return end(); }
|
||
Edge_reverse_iterator edges_rbegin() { return rbegin(); }
|
||
Edge_reverse_iterator edges_rend() { return rend(); }
|
||
// -------------------------------------------------------------------------
|
||
Face_iterator faces_begin() {return Face_iterator(this,begin());}
|
||
Face_const_iterator faces_begin()const{return Face_iterator(this,begin());}
|
||
Face_iterator faces_end() { return Face_iterator(this,end()); }
|
||
Face_const_iterator faces_end() const{ return Face_iterator(this,end()); }
|
||
// -------------------------------------------------------------------------
|
||
Minimals_iterator minimals_begin() { return _minimals_ccw.begin(); }
|
||
Minimals_iterator minimals_end() { return _minimals_ccw.end(); }
|
||
Minimals_iterator cw_minimals_begin() { return _minimals_cw.begin(); }
|
||
Minimals_iterator cw_minimals_end() { return _minimals_cw.end(); }
|
||
Minimals_iterator minimals_begin(Ccw_traits) { return minimals_begin(); }
|
||
Minimals_iterator minimals_end (Ccw_traits) { return minimals_end(); }
|
||
Minimals_iterator minimals_begin(Cw_traits) { return cw_minimals_begin(); }
|
||
Minimals_iterator minimals_end (Cw_traits) { return cw_minimals_end(); }
|
||
// -------------------------------------------------------------------------
|
||
// Iterator pair for linear sweep
|
||
Linear_sweep_iterator sweep_begin()
|
||
{ return Linear_sweep_iterator(this); }
|
||
Linear_sweep_const_iterator sweep_begin() const
|
||
{ return Linear_sweep_const_iterator(this); }
|
||
Linear_sweep_iterator sweep_end()
|
||
{ return Linear_sweep_iterator(this,0); }
|
||
Linear_sweep_const_iterator sweep_end() const
|
||
{ return Linear_sweep_const_iterator(this,0); }
|
||
// -------------------------------------------------------------------------
|
||
// Testing minimality
|
||
template < class _Tr >
|
||
bool is_minimal(const Vertex_handle& v, _Tr tr) const;
|
||
bool is_minimal(const Vertex_handle& v) const
|
||
{ return is_minimal(v,Ccw_traits()); }
|
||
template < class _Tr >
|
||
bool is_xx_minimal(const Vertex_handle& v,_Tr tr) const;
|
||
bool is_right_minimal(const Vertex_handle& v) const
|
||
{ return is_xx_minimal(v,Right_ccw_traits()); }
|
||
bool is_left_minimal(const Vertex_handle& v) const
|
||
{ return is_xx_minimal(v,Left_ccw_traits()); }
|
||
// -------------------------------------------------------------------------
|
||
Vertex_handle pop_minimal(bool finite = false);
|
||
template < class _Tr >
|
||
bool is_swept_regular(const Vertex_handle& v , _Tr tr) const;
|
||
template < class _Tr >
|
||
bool is_swept_constraint(const Vertex_handle& v , _Tr tr) const;
|
||
template < class _Tr >
|
||
bool is_swept(const Vertex_handle& v , _Tr tr) const;
|
||
bool is_swept(const Vertex_handle& v) const
|
||
{ return is_swept(v,Ccw_traits()); }
|
||
// -------------------------------------------------------------------------
|
||
// Adding a minimal
|
||
void push_back_minimal(Vertex_handle v ,Ccw_traits);
|
||
void push_back_minimal(Vertex_handle v ,Cw_traits);
|
||
void push_back_minimal(Vertex_handle v) {push_back_minimal(v,Ccw_traits());}
|
||
// -------------------------------------------------------------------------
|
||
// Removing a minimal
|
||
void erase_minimal(Vertex_handle v, Ccw_traits) { _minimals_ccw.erase(v); }
|
||
void erase_minimal(Vertex_handle v, Cw_traits) { _minimals_cw.erase(v); }
|
||
void erase_minimal(Vertex_handle v) { erase_minimal(v, Ccw_traits()); }
|
||
// Depreciated - for backward compatibility
|
||
template < class _Tr >
|
||
void erase_minimal(Minimals_iterator v,_Tr tr) { erase_minimal(&(*v),tr); }
|
||
void erase_minimal(Minimals_iterator v) { erase_minimal(v,Ccw_traits()); }
|
||
// -------------------------------------------------------------------------
|
||
// Removing all minimals
|
||
template < class _Tr > void clear_minimals(_Tr tr);
|
||
void clear_minimals() { clear_minimals(Ccw_traits()); }
|
||
// -------------------------------------------------------------------------
|
||
// Sweeping - flipping operations
|
||
template < class _Tr > void sweep(Vertex_handle v, _Tr tr);
|
||
template < class _Tr > void sweep_good(Vertex_handle v , _Tr tr);
|
||
template < class _Tr > void sweep_all_minimals(_Tr tr);
|
||
template < class _Tr > void sweep_good_all_minimals(_Tr tr);
|
||
void sweep(Vertex_handle v) { sweep(v,Ccw_traits()); }
|
||
void sweep_all_minimals() { sweep_all_minimals(Ccw_traits()); }
|
||
// -------------------------------------------------------------------------
|
||
void set_constraint(Vertex_handle v);
|
||
void unset_constraint(Vertex_handle v);
|
||
void add_constraint(Vertex_handle v);
|
||
void remove_constraint(Vertex_handle v);
|
||
// -------------------------------------------------------------------------
|
||
protected:
|
||
// -------------------------------------------------------------------------
|
||
// Compute the flipped bitangent phi(v)
|
||
template < class _Tr >
|
||
Vertex_handle compute_phi(Vertex_handle v , _Tr) /*const*/;
|
||
// -------------------------------------------------------------------------
|
||
// Update the antichain while adding a constraint
|
||
template < class _Tr > void sweep_constraint(const Vertex_handle& v, const _Tr&) const;
|
||
template < class _Tr > void sweep_regular (const Vertex_handle& v, const _Tr&) const;
|
||
// -------------------------------------------------------------------------
|
||
// Initialisation methods
|
||
template<class InputIterator , class ConstraintIt>
|
||
void compute_graph(InputIterator first, InputIterator last,
|
||
ConstraintIt firstc,ConstraintIt lastc);
|
||
template < class _Tr > void compute_minimals(_Tr tr);
|
||
template < class _Tr > void compute_vertices(_Tr tr);
|
||
template < class _Tr > void fix_extreme_edges(_Tr tr) const;
|
||
template < class _Tr > void glue_ccw_cw(_Tr tr) const;
|
||
template < class _Tr > void initialize_convex_hull(_Tr tr) const;
|
||
// -------------------------------------------------------------------------
|
||
// Method used during intialization, to compute candidates during the
|
||
// Bentley-Ottmann rotational sweep.
|
||
// template<class _Tr> bool is_candidate(const Face_handle& fa) const;
|
||
template < class _Tr >
|
||
bool
|
||
is_candidate(const Face_handle& f, const _Tr&) const
|
||
{
|
||
typename _Tr::Dl dl; typename _Tr::Ur ur; typename _Tr::Sup sup;
|
||
if (f == 0 || f->top_edge() == 0 || f->bottom_edge() == 0) return false;
|
||
if (sup(f) != 0 && sup(f)->is_constraint()) return is_minimal(sup(f),_Tr());
|
||
if (f->top_edge()->object() == 0 || f->bottom_edge()->object() == 0)
|
||
return false;
|
||
return (ur(f->bottom_edge()) == f && dl(f->top_edge()) == f);
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
#ifdef DEBUG
|
||
public:
|
||
void print(Vertex_handle v) {
|
||
//cout << v << " " << flush;
|
||
if (v == 0) return;
|
||
cout << *v << " , (";
|
||
if (v->is_left_xx()) cout << "+"; else cout << "-";
|
||
cout << Key[long(v->source_object())] << ",";
|
||
if (v->is_xx_left()) cout << "+"; else cout << "-";
|
||
cout << Key[long(v->target_object())] << ")" ;
|
||
/*
|
||
cout << " minLR(" << flush
|
||
<< is_xx_minimal(v,Left_ccw_traits()) << "," << flush
|
||
<< is_xx_minimal(v,Right_ccw_traits()) << ")";
|
||
cout << " cw_minLR(" << flush
|
||
<< is_xx_minimal(v,Left_cw_traits()) << "," << flush
|
||
<< is_xx_minimal(v,Right_cw_traits()) << ")";
|
||
if (is_swept(v)) cout << " swept";
|
||
else cout << " not swept";
|
||
*/
|
||
}
|
||
void print(Edge_handle e, bool coord = true) {
|
||
cout << e << " " << flush;
|
||
if (e == 0) return;
|
||
if (e->object() == 0) {
|
||
if (e == e->sup()->target_cusp_edge())
|
||
cout << "-" << Key[long(e->sup()->target_object())] << "c";
|
||
else cout << "+" << Key[long(e->sup()->source_object())] << "c";
|
||
}
|
||
else {
|
||
if (e->sign()) cout << "+"; else cout << "-";
|
||
cout << Key[long(e->object())] ;
|
||
}
|
||
cout << " {";
|
||
if (e->sign())
|
||
cout << e->dl() << ","
|
||
<< e->ur() << ","
|
||
<< e->ul();
|
||
else cout << e->dl() << ","
|
||
<< e->dr() << ","
|
||
<< e->ul();
|
||
cout << "}";
|
||
if (coord) {
|
||
cout << " [";
|
||
cout << *e->begin() << "," << *--e->end() << "]";
|
||
}
|
||
}
|
||
void print(Face_handle f) {
|
||
cout << f << " " << flush;
|
||
if (f == 0) return;
|
||
cout << "[" ;
|
||
print(f->bottom_edge()); cout << ",";
|
||
print(f->top_edge()); cout << "]";
|
||
cout << " inf = " << f->inf() << " , sup = " << f->sup();
|
||
}
|
||
template < class _Tr >
|
||
void print_left_minimal(Vertex_handle v ,_Tr tr);
|
||
template < class _Tr >
|
||
void print_right_minimal(Vertex_handle v ,_Tr tr);
|
||
#endif
|
||
// -------------------------------------------------------------------------
|
||
};
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Computing the Antichain using a Bentley-Ottman sweep
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class InputIterator , class ConstraintIt >
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
Visibility_complex_antichain(InputIterator first, InputIterator last ,
|
||
ConstraintIt firstc,ConstraintIt lastc)
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// Default values : linear space topological sweep
|
||
_straight_sweep = false;
|
||
_linear_space = true;
|
||
//_linear_space = false;
|
||
// -------------------------------------------------------------------------
|
||
if (first == last) { _valid = false; return; }
|
||
compute_graph(first,last,firstc,lastc);
|
||
if (!is_valid()) return;
|
||
// -------------------------------------------------------------------------
|
||
compute_vertices(Ccw_traits());
|
||
compute_vertices(Cw_traits());
|
||
// -------------------------------------------------------------------------
|
||
fix_extreme_edges(Ccw_traits());
|
||
fix_extreme_edges(Cw_traits());
|
||
// -------------------------------------------------------------------------
|
||
glue_ccw_cw(Ccw_traits());
|
||
glue_ccw_cw(Cw_traits());
|
||
// -------------------------------------------------------------------------
|
||
initialize_convex_hull(Ccw_traits());
|
||
initialize_convex_hull(Cw_traits());
|
||
// -------------------------------------------------------------------------
|
||
compute_minimals(Ccw_traits());
|
||
compute_minimals(Cw_traits());
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class InputIterator , class ConstraintIt >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
compute_graph(InputIterator first, InputIterator last,
|
||
ConstraintIt firstc,ConstraintIt lastc)
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// The pseudo-triangulation is valid if no pair of objects intersect
|
||
CGAL_expensive_precondition_code( Do_intersect<Self> do_intersect; );
|
||
_valid = true;
|
||
// -------------------------------------------------------------------------
|
||
// X-structure containing the nodes of the antichain == edges of
|
||
// Visibility graph
|
||
typedef std::priority_queue<Edge_handle,
|
||
std::vector<Edge_handle>,
|
||
Less_edge_handle<_Gtr> > Xstructure;
|
||
Xstructure XE;
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Map to keep track of the edge with opposite sign
|
||
std::map<long,Edge_handle> opposite;
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Creating the edges and pushing them in the priority queue
|
||
typename Ccw_traits::Set_adjacent_faces_one_to_one set_adjacent_faces;
|
||
// Regular edges - two per disk
|
||
for (InputIterator it = first; it != last ; ++it ) {
|
||
Edge_handle neg = new Edge(false,&(*it));
|
||
Edge_handle pos = new Edge(true,&(*it));
|
||
push_back(*neg); push_back(*pos);
|
||
XE.push(neg); XE.push(pos);
|
||
set_adjacent_faces(neg,new Face,new Face,0);
|
||
set_adjacent_faces(pos,new Face,0,0);
|
||
neg->dl()->set_front_view(neg);
|
||
neg->dr()->set_back_view(pos);
|
||
opposite[long(neg)] = pos;
|
||
opposite[long(pos)] = neg;
|
||
neg->set_opposite(pos);
|
||
}
|
||
// Constraint edges - two per constraint
|
||
// We make sure the constraint is upward directed
|
||
typename _Gtr::Is_upward_directed is_upward_directed;
|
||
for (ConstraintIt c = firstc; c != lastc ; ++c ) {
|
||
CGAL_precondition(c->sup() == 0);
|
||
if (!c->is_constraint()) set_constraint(&(*c));
|
||
if (!c->pi()->is_constraint()) set_constraint(c->pi());
|
||
Vertex_handle d = (is_upward_directed(*c)) ? &(*c) : c->pi();
|
||
push_back(*d->target_cusp_edge());
|
||
push_back(*d->source_cusp_edge());
|
||
XE.push(d->target_cusp_edge());
|
||
XE.push(d->source_cusp_edge());
|
||
}
|
||
if (XE.size() == 2) { _valid = false; return; }
|
||
// -------------------------------------------------------------------------
|
||
#ifdef DEBUG
|
||
int index = 1;
|
||
for (Edge_iterator e = edges_begin(); e != edges_end(); ++e)
|
||
{
|
||
if (!e->sign()) {
|
||
Key[long(e->object())] = index;
|
||
Key[long(&(*e))] = -index;
|
||
}
|
||
else {
|
||
Key[long(&(*e))] = +index;
|
||
++index;
|
||
}
|
||
}
|
||
#endif
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Y-structure containing at each moment the ordered list of object
|
||
// intersected by the sweeping line.
|
||
// The faces are ordered by their front view
|
||
// An object is represented by a pair of faces (f1,f2) such that
|
||
// f1->front_object() == f2->back_object()
|
||
typedef std::set<Face_handle,Less_face_handle<Self> > Ystructure;
|
||
Ystructure YE;
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Splice function object used when inserting a constraint
|
||
typename Ccw_traits::Splice splice_ccw;
|
||
typename Cw_traits::Splice splice_cw;
|
||
// -------------------------------------------------------------------------
|
||
// The infinite face helps us to identify the convex-hull vertices
|
||
_infinite_face = new Face;
|
||
_infinite_face->set_bottom_edge(XE.top());
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Start of the Bentley-Ottman sweep
|
||
Face_handle infinite = NULL;
|
||
while ( !XE.empty() && _valid ) {
|
||
Edge_handle pe = XE.top(); XE.pop();
|
||
// ---------------------------------------------------------------------
|
||
// Treating a node with in_degree 2 and out_degree 1
|
||
if (!pe->sign()) {
|
||
// -----------------------------------------------------------------
|
||
// Inserting a Regular Edge
|
||
if (pe->object() != 0) { // regular Edge
|
||
// -------------------------------------------------------------
|
||
// Insert two new faces in YE
|
||
Face_handle upleft = new Face; upleft->set_front_view(pe);
|
||
typename Ystructure::iterator upleft_it = YE.upper_bound(upleft);
|
||
delete upleft;
|
||
if ( upleft_it == YE.end() ) upleft = infinite;
|
||
else { upleft = *upleft_it; YE.erase(upleft_it); }
|
||
set_adjacent_faces(pe,pe->dl(),pe->dr(),upleft);
|
||
if (upleft != 0) {
|
||
// ---------------------------------------------------------
|
||
CGAL_expensive_precondition_code(
|
||
_valid = !do_intersect(pe->ul()->back_view(),pe);
|
||
if (_valid == false) return;
|
||
_valid = !do_intersect(pe->ul()->front_view(),pe);
|
||
if (_valid == false) return;
|
||
);
|
||
// ---------------------------------------------------------
|
||
pe->dr()->set_front_view(pe->ul()->front_view());
|
||
pe->dl()->set_back_view (pe->ul()->back_view());
|
||
}
|
||
YE.insert(pe->dl()); YE.insert(pe->dr());
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
// Inserting a cusp Edge from an xx-left constraint
|
||
else if (pe->sup()->is_xx_left()) {
|
||
// -------------------------------------------------------------
|
||
// Find the place where to insert the constraint
|
||
Face_handle right = new Face; right->set_front_view(pe);
|
||
typename Ystructure::iterator right_it = YE.upper_bound(right);
|
||
CGAL_precondition( right_it != YE.end() );
|
||
delete right; right = *right_it;
|
||
// -------------------------------------------------------------
|
||
CGAL_expensive_precondition_code(
|
||
_valid = !do_intersect(right->front_view(),pe);
|
||
if (_valid == false) return;
|
||
);
|
||
// -------------------------------------------------------------
|
||
// Splitting the boundary of the target object of pe->sup()
|
||
CGAL_precondition(right->back_view()->object() != 0);
|
||
splice_ccw(right->back_view(),pe->sup());
|
||
// -------------------------------------------------------------
|
||
pe->dl()->set_back_view (pe->sup()->cw_target_edge());
|
||
pe->dl()->set_front_view(pe);
|
||
right->set_back_view(pe);
|
||
YE.insert(pe->dl());
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
// Inserting a cusp Edge from an xx-right constraint
|
||
else {
|
||
// -------------------------------------------------------------
|
||
// Find the place where to insert the constraint
|
||
Face_handle left = new Face; left->set_front_view(pe);
|
||
typename Ystructure::iterator left_it = YE.upper_bound(left);
|
||
CGAL_precondition( left_it != YE.end() );
|
||
delete left; left = *left_it;
|
||
YE.erase(left_it);
|
||
// -------------------------------------------------------------
|
||
CGAL_expensive_precondition_code(
|
||
_valid = !do_intersect(left->back_view(),pe);
|
||
if (_valid == false) return;
|
||
);
|
||
// -------------------------------------------------------------
|
||
CGAL_precondition(left->front_view()->object() != 0);
|
||
splice_ccw(left->front_view(),pe->sup());
|
||
// -------------------------------------------------------------
|
||
pe->dr()->set_back_view (pe);
|
||
pe->dr()->set_front_view(pe->sup()->ccw_target_edge());
|
||
left->set_front_view(pe);
|
||
YE.insert(left); YE.insert(pe->dr());
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
}
|
||
// ---------------------------------------------------------------------
|
||
// Treating a node with in_degree 1 and out_degree 2
|
||
else {
|
||
// -----------------------------------------------------------------
|
||
// Inserting a regular Edge
|
||
if (pe->object() != 0) {
|
||
// -------------------------------------------------------------
|
||
// Find the two adjacent faces in YE that connect to pe and
|
||
// erase them from YE.
|
||
Face_handle tmpf = new Face; tmpf->set_front_view(pe);
|
||
typename Ystructure::iterator it1 = YE.find(tmpf);
|
||
typename Ystructure::iterator it2 = it1; ++it2;
|
||
Face_handle upleft = *it1; Face_handle upright = *it2;
|
||
delete tmpf; YE.erase(it1); YE.erase(it2);
|
||
// -------------------------------------------------------------
|
||
// Update existing faces
|
||
if ( XE.empty() ) {
|
||
delete pe->dl();
|
||
set_adjacent_faces(pe,0,upright,upleft);
|
||
}
|
||
else {
|
||
set_adjacent_faces(pe,pe->dl(),upright,upleft);
|
||
pe->dl()->set_front_view(upright->front_view());
|
||
pe->dl()->set_back_view (upleft->back_view());
|
||
// ---------------------------------------------------------
|
||
CGAL_expensive_precondition_code(
|
||
_valid = !do_intersect(pe->dl()->back_view(),
|
||
pe->dl()->front_view());
|
||
if (_valid == false) return;
|
||
);
|
||
// ---------------------------------------------------------
|
||
YE.insert(pe->dl());
|
||
}
|
||
// -------------------------------------------------------------
|
||
infinite = pe->dl();
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
// Inserting a tail cusp Edge from an left-xx constraint
|
||
else if (pe->sup()->is_left_xx()) {
|
||
// -------------------------------------------------------------
|
||
// Find the face in YE with pe->sup() as a front view.
|
||
Face_handle upleft = new Face;
|
||
upleft->set_front_view(pe->sup()->target_cusp_edge());
|
||
typename Ystructure::iterator upleft_it = YE.find(upleft);
|
||
typename Ystructure::iterator right = upleft_it; ++right;
|
||
delete upleft; upleft = *upleft_it;
|
||
YE.erase(upleft_it);
|
||
// -------------------------------------------------------------
|
||
// Update degenerate face emanating from edge.
|
||
upleft->set_sup(pe->sup());
|
||
upleft->set_inf(pe->sup()->pi());
|
||
CGAL_precondition(upleft->back_view()->object() != 0);
|
||
splice_ccw(upleft->back_view(),pe->sup());
|
||
// -------------------------------------------------------------
|
||
/* delete pe->ul(); */ set_adjacent_faces(pe,0,0,upleft);
|
||
CGAL_precondition(pe->dl() == 0 && pe->ur() == 0);
|
||
// -------------------------------------------------------------
|
||
// Update the back view of right.
|
||
(*right)->set_back_view(pe->sup()->cw_source_edge());
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
// Inserting a tail cusp Edge from a right-xx constraint
|
||
else {
|
||
// -------------------------------------------------------------
|
||
// Find the face in YE with pe->sup() as a front view.
|
||
Face_handle left = new Face;
|
||
left->set_front_view(pe->sup()->target_cusp_edge());
|
||
typename Ystructure::iterator left_it = YE.find(left);
|
||
typename Ystructure::iterator upright = left_it; ++upright;
|
||
delete left; left = *left_it;
|
||
// -------------------------------------------------------------
|
||
// Set upright as the degenerate face of the edge pe.
|
||
(*upright)->set_sup(pe->sup());
|
||
(*upright)->set_inf(pe->sup()->pi());
|
||
CGAL_precondition((*upright)->front_view()->object() != 0);
|
||
splice_ccw((*upright)->front_view(),pe->sup());
|
||
// -------------------------------------------------------------
|
||
/* delete pe->ur(); */ set_adjacent_faces(pe,0,*upright,0);
|
||
CGAL_precondition(pe->dl() == 0 && pe->ul() == 0);
|
||
// -------------------------------------------------------------
|
||
// Update the back view of left and insert the face.
|
||
YE.erase(left_it); YE.erase(upright);
|
||
left->set_front_view(pe->sup()->ccw_source_edge());
|
||
YE.insert(left);
|
||
// -------------------------------------------------------------
|
||
}
|
||
// -----------------------------------------------------------------
|
||
}
|
||
if (XE.empty()) _infinite_face->set_top_edge(pe);
|
||
} // end while ( !XE.empty() )
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Splicing the boundary of objects by inserting the pi of the constraints
|
||
// The fact that the edges come in pairs allows us to recover the edge with
|
||
// opposite sign on the same disk.
|
||
for (Edge_iterator e = edges_begin(); e != edges_end() ; ++e) {
|
||
if (e->object() != 0 && e->sup() != 0) {
|
||
Edge_handle eo = opposite[long(&(*e))];
|
||
CGAL_precondition(eo == e->opposite());
|
||
|
||
Vertex_handle v = e->sup();
|
||
splice_cw(eo,v->pi());
|
||
while (v->ccw_edge(e->object())->sup() != 0) {
|
||
splice_cw(v->pi()->ccw_edge(e->object()),
|
||
v->ccw_edge(e->object())->sup()->pi());
|
||
v = v->ccw_edge(e->object())->sup();
|
||
}
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
/*
|
||
// put inline
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_candidate(const Face_handle& f) const
|
||
{
|
||
typename _Tr::Dl dl; typename _Tr::Ur ur; typename _Tr::Sup sup;
|
||
if (f == 0 || f->top_edge() == 0 || f->bottom_edge() == 0) return false;
|
||
if (sup(f) != 0 && sup(f)->is_constraint()) return is_minimal(sup(f),_Tr());
|
||
if (f->top_edge()->object() == 0 || f->bottom_edge()->object() == 0)
|
||
return false;
|
||
return (ur(f->bottom_edge()) == f && dl(f->top_edge()) == f);
|
||
}
|
||
*/
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::compute_vertices(_Tr tr)
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// All the operators from this methods are taken from the algorithm traits
|
||
// class _Tr. Two traits classes are given : Ccw_traits and Cw_traits to
|
||
// compute G and G_* respectively
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
typename _Tr::Set_sup set_sup;// typename _Tr::Set_inf set_inf;
|
||
typename _Tr::Vertex_creator vc;
|
||
typename _Tr::Set_adjacent_faces set_adjacent_old_faces;
|
||
typename _Tr::Set_adjacent_faces_one_to_one set_adjacent_faces;
|
||
typename _Tr::Dr dr; typename _Tr::Dl dl;
|
||
typename _Tr::Ur ur; typename _Tr::Ul ul;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Splice splice;
|
||
typedef _Tr TR;
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Saving the Edge --> Face pointers because we will loose them during the
|
||
// rotational sweep below
|
||
Self a;
|
||
for (Edge_iterator e = edges_begin(); e != edges_end() ; ++e) {
|
||
Edge_handle tmp = new Edge; tmp->set_sign(e->sign());
|
||
a.push_back(*tmp);
|
||
if (e->sign())
|
||
set_adjacent_old_faces(&a.back(),dl(&(*e)),ur(&(*e)),ul(&(*e)));
|
||
else set_adjacent_old_faces(&a.back(),dl(&(*e)),dr(&(*e)),ul(&(*e)));
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// death is the event queue.
|
||
// It contains the vertices which are about to appear.
|
||
// Pushing first candidates to initialize death vertices
|
||
std::set<Vertex_handle,typename _Tr::Less_vertex_handle> death;
|
||
|
||
for (Face_iterator fit = faces_begin() ; fit != faces_end() ; ++fit) {
|
||
Face_handle f = &(*fit);
|
||
if (is_candidate(f, _Tr())) { // af: gcc needs it, for bcc it must not be there
|
||
if (sup(f) == 0) set_sup(f,vc(f->bottom_edge(),f->top_edge()));
|
||
death.insert(sup(f));
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Rotational sweep <20> la Bentley-Otman
|
||
while ( death.size() != 0 ) {
|
||
Vertex_handle vmin = *death.begin();
|
||
death.erase(death.begin());
|
||
// ---------------------------------------------------------------------
|
||
Edge_handle top = (vmin->is_constraint()) ? cw_target_edge(vmin) :
|
||
inf(vmin)->top_edge();
|
||
Edge_handle bot = (vmin->is_constraint()) ? cw_source_edge(vmin) :
|
||
inf(vmin)->bottom_edge();
|
||
// ---------------------------------------------------------------------
|
||
// A new Vertex ( == bitangent) has been found
|
||
// splice the two edges defining it
|
||
if (vmin != sup(top)) splice(top,vmin);
|
||
if (vmin != sup(bot)) splice(bot,vmin);
|
||
// ---------------------------------------------------------------------
|
||
// The two possible adjacent candidates must be erased
|
||
Face_handle ef[6];
|
||
if (bot->sign()) { ef[0] = dl(bot); ef[1] = ur(bot); ef[2] = ul(bot); }
|
||
else { ef[0] = dl(bot); ef[1] = dr(bot); ef[2] = ul(bot); }
|
||
if (top->sign()) { ef[3] = dl(top); ef[4] = ur(top); ef[5] = ul(top); }
|
||
else { ef[3] = dl(top); ef[4] = dr(top); ef[5] = ul(top); }
|
||
for (int i = 0 ; i < 6 ; i++)
|
||
if (is_candidate(ef[i], _Tr()) && sup(ef[i]) != vmin) {
|
||
death.erase(sup(ef[i]));
|
||
if (!sup(ef[i])->is_constraint()) set_sup(ef[i],0);
|
||
}
|
||
// ---------------------------------------------------------------------
|
||
// Update the antichain
|
||
CGAL_precondition(sup(vmin) == 0);
|
||
sweep_constraint(vmin, _Tr());
|
||
set_adjacent_old_faces(top,0,0,0);
|
||
set_adjacent_old_faces(bot,0,0,0);
|
||
// ---------------------------------------------------------------------
|
||
// Computing new candidates by looking at the adjacent faces of
|
||
// bot and top.
|
||
bot = ccw_source_edge(vmin);
|
||
top = ccw_target_edge(vmin);
|
||
if (sup(bot) != 0 && sup(bot)->is_constraint() &&
|
||
is_minimal(sup(bot),tr))
|
||
death.insert(sup(bot));
|
||
if (sup(top) != 0 && sup(top)->is_constraint() &&
|
||
is_minimal(sup(top),tr))
|
||
death.insert(sup(top));
|
||
Face_handle af[] = { dl(bot) , ur(bot) , dl(top) , ur(top) };
|
||
for (int i = 0 ; i < 4 ; i++)
|
||
if (is_candidate(af[i], _Tr()) &&
|
||
sup(af[i]) != vmin && sup(af[i]) != vmin->pi()) {
|
||
if (sup(af[i]) == 0) set_sup(af[i],vc(af[i]->bottom_edge(),
|
||
af[i]->top_edge()));
|
||
death.insert(sup(af[i]));
|
||
}
|
||
// ---------------------------------------------------------------------
|
||
} // end while (death.size() != 0)
|
||
|
||
// -------------------------------------------------------------------------
|
||
// Recovering the initial Edge --> Face pointers with a
|
||
Edge_iterator ea = a.edges_begin();
|
||
for (Edge_iterator e = edges_begin(); e != edges_end() ; ++e,++ea) {
|
||
if (e->sign())
|
||
set_adjacent_faces(&(*e),dl(&(*ea)),ur(&(*ea)),ul(&(*ea)));
|
||
else set_adjacent_faces(&(*e),dl(&(*ea)),dr(&(*ea)),ul(&(*ea)));
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::compute_minimals(_Tr tr)
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// Operators used in this method.
|
||
typename _Tr::Sup sup;
|
||
typedef typename _Tr::Right_traits Right_traits;
|
||
typename Right_traits::Target_cusp_edge target_cusp_edge;
|
||
typename Right_traits::Top_edge top_edge;
|
||
// -------------------------------------------------------------------------
|
||
// Computing the set of minimal bitangents
|
||
Vertex_handle ll = 0, rr = 0;
|
||
for (Face_iterator fi = faces_begin(); fi != faces_end() ; ++fi) {
|
||
Face_handle f = &(*fi);
|
||
if (sup(f) != 0 && is_minimal(sup(f),tr)) {
|
||
if (!sup(f)->is_constraint() ||
|
||
top_edge(f) == target_cusp_edge(sup(f))) {
|
||
Vertex_handle v = sup(f);
|
||
if (v != ll && v != rr) push_back_minimal(sup(f),tr);
|
||
if (ll == 0 && v->is_left_left() &&
|
||
is_on_convex_hull(v)) ll = v;
|
||
else if (rr == 0 && v->is_right_right() &&
|
||
is_on_convex_hull(v)) rr = v;
|
||
}
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Find topmost and bottommost edge.
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
initialize_convex_hull(_Tr /*tr*/) const
|
||
{
|
||
typename _Tr::Set_adjacent_faces set_adjacent_faces;
|
||
typename _Tr::Dr dr; typename _Tr::Dl dl;
|
||
typename _Tr::Ur ur; typename _Tr::Ul ul;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
typename _Tr::Sup sup;
|
||
|
||
Edge_handle e = infinite_face()->bottom_edge();
|
||
do {
|
||
e = ccw_source_edge(sup(e));
|
||
set_adjacent_faces(e,dl(e),dr(e),infinite_face());
|
||
} while (e != infinite_face()->bottom_edge());
|
||
|
||
e = infinite_face()->top_edge();
|
||
do {
|
||
e = ccw_target_edge(sup(e));
|
||
set_adjacent_faces(e,infinite_face(), ur(e),ul(e));
|
||
} while (e != infinite_face()->top_edge());
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// The antichain has 3n-1 faces whereas the pseudo-triangulation has only 3n-3
|
||
// bitangents. There are two faces which do not have their sup pointer set at
|
||
// this point. These are ul(bottommost) and dr(topmost). This function sets the
|
||
// sink of the two supplementary faces.
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::fix_extreme_edges(_Tr /*tr*/) const // warning tr is never used
|
||
{
|
||
//--------------------------------------------------------------------------
|
||
// Operators used in this method.
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
typename _Tr::Set_sup set_sup; typename _Tr::Set_inf set_inf;
|
||
typename _Tr::Dr dr; typename _Tr::Dl dl;
|
||
typename _Tr::Ur ur; typename _Tr::Ul ul;
|
||
typename _Tr::CcL ccL; typename _Tr::CcR ccR;
|
||
typename _Tr::Set_adjacent_faces set_adjacent_faces;
|
||
typename _Tr::Ccw_edge ccw_edge;
|
||
typename _Tr::Splice splice;
|
||
// -------------------------------------------------------------------------
|
||
Edge_handle bot = infinite_face()->top_edge(); // Bottommost edge
|
||
Edge_handle top = infinite_face()->bottom_edge(); // Topmost edge
|
||
set_adjacent_faces(bot,infinite_face(),ur(bot),ul(bot));
|
||
set_adjacent_faces(top,dl(top),dr(top),infinite_face());
|
||
// -------------------------------------------------------------------------
|
||
// A face may appear twice in the antichain due to our identification
|
||
// v = v->pi()->pi(). If this is the case, delete one of the two and update
|
||
// pointers.
|
||
if (ur(bot) == dr(top) && ul(bot) != dl(top)) {
|
||
Edge_handle t = ul(bot)->top_edge();
|
||
set_inf(dl(top),inf(ul(bot)));
|
||
if (t->sign()) set_adjacent_faces(t,dl(top),ur(t),ul(t));
|
||
else set_adjacent_faces(t,dl(top),dr(t),ul(t));
|
||
dl(top)->set_top_edge(t);
|
||
set_adjacent_faces(bot,dr(bot),ur(bot),dl(top));
|
||
// delete ul(bot);
|
||
}
|
||
else if (ul(bot) == dl(top) && ur(bot) != dr(top)) {
|
||
Edge_handle t = dr(top)->bottom_edge();
|
||
set_inf(ur(bot),inf(dr(top)));
|
||
if (!t->sign()) set_adjacent_faces(t,dl(t),dr(t),ur(bot));
|
||
else set_adjacent_faces(t,dl(t),ur(bot),ul(t));
|
||
ur(bot)->set_bottom_edge(t);
|
||
set_adjacent_faces(top,dl(top),ur(bot),ul(top));
|
||
// delete dr(top);
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Set the sink of the two faces on the convex-hull.
|
||
if (sup(ur(bot)) != 0 && sup(ul(bot)) == 0) {
|
||
Vertex_handle v = sup(ur(bot));
|
||
Vertex_handle w = inf(dr(top));
|
||
if (*v == *w->pi()) set_sup(ul(bot),w);
|
||
else {
|
||
do { v = ccR(v); } while (v->is_constraint());
|
||
CGAL_precondition(v != 0 && inf(v) != 0);
|
||
set_sup(ul(bot),inf(inf(v)));
|
||
}
|
||
sup(ur(bot))->set_pi(sup(ul(bot)));
|
||
}
|
||
if (sup(dl(top)) != 0 && sup(dr(top)) == 0) {
|
||
Vertex_handle v = sup(dl(top));
|
||
Vertex_handle w = inf(ul(bot));
|
||
if (*v == *w->pi()) set_sup(dr(top),w);
|
||
else {
|
||
do { v = ccL(v); } while (v->is_constraint());
|
||
CGAL_precondition(v != 0 && inf(v) != 0);
|
||
set_sup(dr(top),inf(inf(v)));
|
||
}
|
||
sup(dl(top))->set_pi(sup(dr(top)));
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Due to the problem of the face appearing twice in the antichain, it is
|
||
// possible that sup(bot) or sup(top) is 0. We fix this.
|
||
//CGAL_precondition(sup(bot) != 0 || sup(top) != 0);
|
||
if (sup(bot) == 0) {
|
||
CGAL_precondition(sup(top) != 0);
|
||
CGAL_precondition(inf(bot) != 0);
|
||
splice(ccw_edge(inf(bot),bot->object()), sup(top)->pi());
|
||
}
|
||
else if (sup(top) == 0) {
|
||
CGAL_precondition(sup(bot) != 0);
|
||
CGAL_precondition(inf(top) != 0);
|
||
splice(ccw_edge(inf(top),top->object()), sup(bot)->pi());
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
CGAL_precondition(sup(bot) != 0);
|
||
CGAL_precondition(sup(top) != 0);
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// This function glues the last arc of G to the first arc of G_*.
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::glue_ccw_cw(_Tr /*tr*/) const // warning tr is never used
|
||
{
|
||
//--------------------------------------------------------------------------
|
||
// Operators used in this method.
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
typename _Tr::Ccw_edge ccw_edge; typename _Tr::Cc cc;
|
||
typename _Tr::Splice splice;
|
||
// -------------------------------------------------------------------------
|
||
// Let eo be the edge on the same object as e but with opposite sign.
|
||
// Let vmax be the maximal bitangent leaving the disk of e.
|
||
// Let vmin = sup(eo) be the minimal bitangent leaving the disk of eo.
|
||
// We set the pointer sup(ccw_edge(vmax,e->object())) = pi(vmin)
|
||
for (Edge_const_iterator e = edges_begin(); e != edges_end() ; ++e) {
|
||
if (e->object() != 0) {
|
||
Edge_const_iterator eo = e; if (e->sign()) --eo; else ++eo;
|
||
Vertex_handle vmin = inf(&(*eo));
|
||
Vertex_handle vmax = sup(&(*e));
|
||
while (cc(vmax,e->object()) != 0 && *vmax != *vmin->pi())
|
||
vmax = cc(vmax,e->object());
|
||
if (*vmax == *vmin->pi()) {
|
||
if (vmax != vmin->pi()) delete vmin->pi();
|
||
vmin->set_pi(vmax);
|
||
}
|
||
else splice(ccw_edge(vmax,e->object()),vmin->pi());
|
||
Edge_handle f = ccw_edge(vmax,e->object()); // Fixed 050701
|
||
if (f != &(*e)) f->set_adjacent_faces(0,0,0);// Fixed 050701
|
||
//ccw_edge(vmax,e->object())->set_adjacent_faces(0,0,0);
|
||
CGAL_precondition(inf(ccw_edge(vmax,e->object())) == vmax);
|
||
splice(ccw_edge(vmin->pi(),e->object()),sup(&(*eo))->pi());
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Identifying vertices of the convex-hull
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
inline bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_on_convex_hull(Vertex_handle v) const
|
||
{
|
||
return ((v->is_left_left() && v->cw_source_edge() != 0 &&
|
||
v->cw_source_edge()->dr() == infinite_face()) ||
|
||
(v->is_right_right() && v->cw_target_edge() != 0 &&
|
||
v->cw_target_edge()->ul() == infinite_face()));
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Minimality Testing
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
inline bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_minimal(const Vertex_handle& v, _Tr /*tr*/) const
|
||
{
|
||
typename _Tr::Left_traits lt;
|
||
typename _Tr::Right_traits rt;
|
||
return (is_xx_minimal(v,lt) &&
|
||
is_xx_minimal(v,rt));
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
inline bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_xx_minimal(const Vertex_handle& v, _Tr /*tr*/ ) const
|
||
{
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Bottom_edge bottom_edge;
|
||
typename _Tr::Top_edge top_edge;
|
||
typename _Tr::Is_left_xx is_left_xx;
|
||
typename _Tr::Left_cw_traits left_cw_traits;
|
||
typename _Tr::Right_cw_traits right_cw_traits;
|
||
if (v == 0 || cw_source_edge(v) == 0) return false;
|
||
|
||
if (is_on_convex_hull(v)) {
|
||
typename _Tr::CcL ccL; typename _Tr::CwR cwR;
|
||
if (is_left_xx(v))
|
||
return cw_source_edge(v) == top_edge(infinite_face());
|
||
else if (ccL(cwR(v)) == v)
|
||
return is_xx_minimal(cwR(v), left_cw_traits);
|
||
else return is_xx_minimal(cwR(v), right_cw_traits);
|
||
}
|
||
|
||
if (v->is_constraint() || v->pi()->is_constraint()) {
|
||
typename _Tr::Ul ul; typename _Tr::Dr dr;
|
||
typename _Tr::Ur ur; typename _Tr::Dl dl;
|
||
if (is_left_xx(v)) {
|
||
Face_handle f = ur(cw_source_edge(v));
|
||
if (f == 0) f = ul(cw_source_edge(v));
|
||
return (f != 0 && bottom_edge(f) == cw_source_edge(v));
|
||
}
|
||
else {
|
||
Face_handle f = dl(cw_source_edge(v));
|
||
if (f == 0) f = dr(cw_source_edge(v));
|
||
return (f != 0 && top_edge(f) == cw_source_edge(v));
|
||
}
|
||
}
|
||
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
Face_handle f = inf(v);
|
||
return (f != 0 && bottom_edge(f) != 0 && v == sup(bottom_edge(f)));
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
inline void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
print_left_minimal(Vertex_handle v, _Tr tr)
|
||
{
|
||
cerr << "Not implemented" << endl;
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
inline void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
print_right_minimal(Vertex_handle v, _Tr tr)
|
||
{
|
||
cerr << "Not implemented" << endl;
|
||
}
|
||
#endif
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Methods to manage the list of minimals
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::clear_minimals(_Tr tr) {
|
||
Minimals_iterator first = minimals_begin(tr);
|
||
Minimals_iterator last = minimals_end(tr);
|
||
while (first != last) erase_minimal(first++,tr);
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
push_back_minimal(Vertex_handle v,Ccw_traits)
|
||
{
|
||
Less_bitangent<_Gtr> lv;
|
||
Minimals_iterator w = (is_straight()) ? std::lower_bound(minimals_begin(),
|
||
minimals_end(),
|
||
*v,lv) :
|
||
minimals_end();
|
||
_minimals_ccw.insert(w,*v);
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
push_back_minimal(Vertex_handle v,Cw_traits)
|
||
{
|
||
Greater_bitangent<_Gtr> lv;
|
||
Minimals_iterator w = (is_straight()) ? std::lower_bound(cw_minimals_begin(),
|
||
cw_minimals_end(),
|
||
*v,lv) :
|
||
cw_minimals_end();
|
||
_minimals_cw.insert(w,*v);
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
typename Visibility_complex_antichain<_Gtr,It,Flip>::Vertex_handle
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::pop_minimal(bool finite/* = false*/)
|
||
{
|
||
if (minimals_begin() == minimals_end()) return 0;
|
||
if (finite == false) {
|
||
Vertex_handle min = &(*minimals_begin());
|
||
return min;
|
||
}
|
||
else {
|
||
Vertex_handle min = pop_minimal(false);
|
||
if (min != 0 && is_on_convex_hull(min)) return min;
|
||
while (minimals_begin() != minimals_end() &&
|
||
min->sup() != 0 && !is_on_convex_hull(min)) {
|
||
erase_minimal(min);
|
||
min = pop_minimal(false);
|
||
}
|
||
if (min != 0 && is_on_convex_hull(min)) return min;
|
||
return (min == 0 || min->sup() != 0) ? 0 : min;
|
||
}
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::sweep(Vertex_handle v , _Tr tr)
|
||
{
|
||
//--------------------------------------------------------------------------
|
||
// Operators used in this method.
|
||
typename _Tr::Inf inf; typename _Tr::Sup sup;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Ccw_edge ccw_edge; typename _Tr::Cw_edge cw_edge;
|
||
typename _Tr::Cc cc;
|
||
typename _Tr::CcR ccR; typename _Tr::CcL ccL;
|
||
typename _Tr::CwR cwR; typename _Tr::CwL cwL;
|
||
typename _Tr::Splice splice;
|
||
typename _Tr::Source_object source_object;
|
||
typename _Tr::Target_object target_object;
|
||
typename _Tr::Merge merge(this);
|
||
//--------------------------------------------------------------------------
|
||
CGAL_precondition(is_minimal(v,tr));
|
||
CGAL_precondition(cwL(v) != 0 && cwR(v) != 0);
|
||
//--------------------------------------------------------------------------
|
||
// Erasing the edges that are about to be swept
|
||
erase(cw_source_edge(v));
|
||
erase(cw_target_edge(v));
|
||
// -------------------------------------------------------------------------
|
||
// Removing cwR(v) and cwL(v) from the minimal list corresponding to the
|
||
// opposite orientation. Adding v.
|
||
typename _Tr::Cw_traits cw_traits;
|
||
erase_minimal(v,tr); push_back_minimal(v,cw_traits);
|
||
if (is_minimal(cwL(v),cw_traits)) erase_minimal(cwL(v),cw_traits);
|
||
if (cwR(v) != cwL(v) && is_minimal(cwR(v),cw_traits))
|
||
erase_minimal(cwR(v),cw_traits);
|
||
// -------------------------------------------------------------------------
|
||
// Fixing operator pi on the source object of v
|
||
if ( cc(cwR(v)->pi(),source_object(v)) != 0 &&
|
||
*cc(cwR(v)->pi(),source_object(v)) == *v->pi())
|
||
v->set_pi(cc(cwR(v)->pi(),source_object(v)));
|
||
if (cwL(v->pi()) != 0 && *cwL(v->pi()) == *cwR(v)->pi())
|
||
cwR(v)->set_pi(cwL(v->pi()));
|
||
// -------------------------------------------------------------------------
|
||
// Arranging Edge <---> Vertex pointer on the source object of v
|
||
if (ccw_edge(cwR(v)->pi(),source_object(v)) == 0)
|
||
splice(cw_target_edge(v->pi()),cwR(v)->pi());
|
||
splice(ccw_edge(cwR(v)->pi(),source_object(v)),v->pi());
|
||
if (linear_space() && !cwR(v)->pi()->is_constraint() &&
|
||
inf(cwR(v)->pi()) == 0) // merge if pi(cwR(v)) notin G
|
||
//!is_on_convex_hull(cwR(v)->pi()))
|
||
merge(cw_edge (cwR(v)->pi(),source_object(v)),
|
||
ccw_edge(cwR(v)->pi(),source_object(v)));
|
||
// -------------------------------------------------------------------------
|
||
// Fixing operator pi on the target object of v
|
||
if ( cc(cwL(v)->pi(),target_object(v)) != 0 &&
|
||
*cc(cwL(v)->pi(),target_object(v)) == *v->pi())
|
||
v->set_pi(cc(cwL(v)->pi(),target_object(v)));
|
||
if (cwR(v->pi()) != 0 && *cwR(v->pi()) == *cwL(v)->pi())
|
||
cwL(v)->set_pi(cwR(v->pi()));
|
||
// -------------------------------------------------------------------------
|
||
// Arranging Edge <---> Vertex pointer on the target object of v
|
||
if (ccw_edge(cwL(v)->pi(),target_object(v)) == 0)
|
||
splice(cw_source_edge(v->pi()),cwL(v)->pi());
|
||
splice(ccw_edge(cwL(v)->pi(),target_object(v)),v->pi());
|
||
if (linear_space() && !cwL(v)->pi()->is_constraint() &&
|
||
inf(cwL(v)->pi()) == 0) // merge if pi(cwL(v)) notin G
|
||
//!is_on_convex_hull(cwR(v)->pi()))
|
||
merge(cw_edge (cwL(v)->pi(),target_object(v)),
|
||
ccw_edge(cwL(v)->pi(),target_object(v)));
|
||
// -------------------------------------------------------------------------
|
||
// Erasing unneeded element to keep the storage linear
|
||
if (linear_space() && !is_on_convex_hull(v) && !v->is_constraint())
|
||
{ delete sup(v->pi()); delete inf(v->pi()); }
|
||
//--------------------------------------------------------------------------
|
||
// Flipping v and updating the antichain
|
||
if (v->is_constraint() && v->pi()->is_constraint()) {
|
||
// ---------------------------------------------------------------------
|
||
//erase(target_cusp_edge(v));
|
||
//erase(source_cusp_edge(v));
|
||
sweep_constraint(v, _Tr());
|
||
//push_back(*target_cusp_edge(v->pi()));
|
||
//push_back(*source_cusp_edge(v->pi()));
|
||
// ---------------------------------------------------------------------
|
||
}
|
||
else {
|
||
// ---------------------------------------------------------------------
|
||
unset_constraint(v);
|
||
unset_constraint(v->pi());
|
||
compute_phi(v,tr); // Flip bitangent in pseudo-triangulation
|
||
sweep_regular(v, _Tr()); // Modify the antichain
|
||
// ---------------------------------------------------------------------
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
// Pushing the two new created edges
|
||
push_back(*ccw_source_edge(v));
|
||
push_back(*ccw_target_edge(v));
|
||
//--------------------------------------------------------------------------
|
||
// Updating minimals
|
||
if (is_minimal(ccL(v),tr)) push_back_minimal(ccL(v),tr);
|
||
if (ccR(v) != ccL(v) && is_minimal(ccR(v),tr)) push_back_minimal(ccR(v),tr);
|
||
//--------------------------------------------------------------------------
|
||
//Removing phis(v) and merging the edges incident to phis
|
||
if (linear_space() && !is_on_convex_hull(v) &&
|
||
inf(v) != 0 && inf(inf(v)) != 0) {
|
||
Vertex_handle phis = inf(inf(v));
|
||
unset_constraint(phis);
|
||
unset_constraint(phis->pi());
|
||
merge(cw_source_edge(phis),ccw_source_edge(phis));
|
||
merge(cw_target_edge(phis),ccw_target_edge(phis));
|
||
delete phis; delete inf(v);
|
||
}
|
||
}
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::sweep_all_minimals(_Tr tr)
|
||
{
|
||
std::list<Vertex_handle> mins;
|
||
for (Minimals_iterator m = minimals_begin(tr); m != minimals_end(tr); ++m)
|
||
mins.push_back(&(*m));
|
||
typename std::list<Vertex_handle>::iterator clic = mins.begin();
|
||
for ( ; clic != mins.end() ; ++clic)
|
||
if (is_minimal(*clic,tr)) sweep(*clic,tr);
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
/*
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::sweep_good(Vertex_handle v,_Tr tr)
|
||
{
|
||
typename _Tr::CcR ccR; typename _Tr::CcL ccL; typename _Tr::Sup sup;
|
||
// typename _Tr::CwR cwR; typename _Tr::CwL cwL;
|
||
// -------------------------------------------------------------------------
|
||
sweep(v,tr);
|
||
// -------------------------------------------------------------------------
|
||
// If ccR(v) and/or ccL(v) are geometrically equal to v and if ccR(v) and/or
|
||
// ccL(v) are minimal, we sweep them.
|
||
bool source_is_point = _Gtr().is_point(*v->source_object());
|
||
bool target_is_point = _Gtr().is_point(*v->target_object());
|
||
if (!source_is_point && !target_is_point) return;
|
||
CGAL_precondition(ccR(v) != 0 && ccL(v) != 0 && sup(sup(v)) != 0);
|
||
Vertex_handle w[] = { ccR(v) , ccL(v) , sup(sup(v)) };
|
||
for (int i = 0; i < 3 ; i++)
|
||
if (v->source_object() == w[i]->source_object() &&
|
||
v->target_object() == w[i]->target_object() &&
|
||
(source_is_point || v->is_left_xx() == w[i]->is_left_xx()) &&
|
||
(target_is_point || v->is_xx_left() == w[i]->is_xx_left()) &&
|
||
is_minimal(w[i],tr))
|
||
sweep(w[i],tr);
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
*/
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::sweep_good(Vertex_handle v,_Tr tr)
|
||
{
|
||
typename _Tr::CcR ccR; typename _Tr::CcL ccL; typename _Tr::Sup sup;
|
||
// typename _Tr::CwR cwR; typename _Tr::CwL cwL;
|
||
// -------------------------------------------------------------------------
|
||
sweep(v,tr);
|
||
// -------------------------------------------------------------------------
|
||
// If ccR(v) and/or ccL(v) are geometrically equal to v and if ccR(v) and/or
|
||
// ccL(v) are minimal, we sweep them.
|
||
CGAL_precondition(ccR(v) != 0 && ccL(v) != 0 && sup(sup(v)) != 0);
|
||
Vertex_handle w[] = { ccR(v) , ccL(v) , sup(sup(v)) };
|
||
typename _Gtr::Equal_as_segments equal_as_segments;
|
||
for (int i = 0; i < 3 ; i++)
|
||
if (equal_as_segments(*v,*w[i]) && is_minimal(w[i],tr))
|
||
sweep(w[i],tr);
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::sweep_good_all_minimals(_Tr tr)
|
||
{
|
||
std::list<Vertex_handle> mins;
|
||
for (Minimals_iterator m = minimals_begin(tr); m != minimals_end(tr); ++m)
|
||
mins.push_back(&(*m));
|
||
typename std::list<Vertex_handle>::iterator clic = mins.begin();
|
||
for ( ; clic != mins.end() ; ++clic)
|
||
if (is_minimal(*clic,tr)) sweep_good(*clic,tr);
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr >
|
||
typename Visibility_complex_antichain<_Gtr,It,Flip>::Vertex_handle
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
compute_phi(Vertex_handle v, _Tr tr) //const
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
typename _Tr::Sup sup;
|
||
typename _Tr::Set_sup set_sup; typename _Tr::Set_inf set_inf;
|
||
typename _Tr::Splice splice;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::CcL ccL; typename _Tr::CcR ccR;
|
||
typename _Tr::Is_left_xx is_left_xx;
|
||
// -------------------------------------------------------------------------
|
||
Vertex_handle phiv; // The new Vertex that we must compute
|
||
// -------------------------------------------------------------------------
|
||
// Vertex has already been swept.
|
||
if (sup(v) != 0) {
|
||
phiv = sup(sup(v));
|
||
if (!is_on_convex_hull(v)) {
|
||
splice(cw_source_edge(phiv),phiv);
|
||
splice(cw_target_edge(phiv),phiv);
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// The pi of the Vertex has already been swept. We use the formula:
|
||
// phi(v)->pi() = phi(v->pi()).
|
||
else if (sup(v->pi()) != 0) {
|
||
if (is_on_convex_hull(v)) {
|
||
if (is_left_xx(v) && ccL(v->pi()) != 0)
|
||
ccR(v)->set_pi(ccL(v->pi()));
|
||
if (!is_left_xx(v) && ccR(v->pi()) != 0)
|
||
ccL(v)->set_pi(ccR(v->pi()));
|
||
}
|
||
phiv = sup(sup(v->pi()))->pi();
|
||
if (!is_on_convex_hull(v)) {
|
||
splice(cw_source_edge(phiv),phiv);
|
||
splice(cw_target_edge(phiv),phiv);
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// We flip v in the current pseudo-triangulation.
|
||
// To compute phi(v) we walk on the incident pseudo-triangles.
|
||
//else phiv = Chi2_strategy(this)(v,tr);
|
||
else phiv = Flip_traits(this)(v,tr);
|
||
// -------------------------------------------------------------------------
|
||
// We splice the arcs left and right if b is not on the convex hull
|
||
//if (!is_on_convex_hull(v)) { splice(right,phiv); splice(left,phiv); }
|
||
// -------------------------------------------------------------------------
|
||
// Creating a new face with source v and sink phi(v)
|
||
if (sup(v) == 0) set_sup(v,new Face);
|
||
set_inf(sup(v),v);
|
||
set_sup(sup(v),phiv);
|
||
// -------------------------------------------------------------------------
|
||
// Creating a new face with source pi(v) and sink pi(phi(v))
|
||
if (sup(v->pi()) == 0) set_sup(v->pi(),new Face);
|
||
set_inf(sup(v->pi()),v->pi());
|
||
set_sup(sup(v->pi()),phiv->pi());
|
||
// -------------------------------------------------------------------------
|
||
CGAL_precondition(sup(v) != 0 && sup(sup(v)) != 0);
|
||
return phiv;
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::set_constraint(Vertex_handle v)
|
||
{
|
||
typedef Ccw_traits _Tr;
|
||
typename _Tr::Set_sup set_sup; typename _Tr::Set_inf set_inf;
|
||
typename _Tr::Set_adjacent_faces_one_to_one set_adjacent_faces;
|
||
typename _Tr::Set_target_cusp_edge set_target_cusp_edge;
|
||
typename _Tr::Set_source_cusp_edge set_source_cusp_edge;
|
||
typename _Tr::Target_cusp_edge target_cusp_edge;
|
||
typename _Tr::Source_cusp_edge source_cusp_edge;
|
||
typename _Tr::Is_left_xx is_left_xx;
|
||
typename _Tr::Is_xx_left is_xx_left;
|
||
// -------------------------------------------------------------------------
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
Face_handle fs = sup(v); Face_handle fi = inf(v);
|
||
Face_handle pifs = sup(v->pi()); Face_handle pifi = inf(v->pi());
|
||
// -------------------------------------------------------------------------
|
||
// New edge for rays emanating from b->target() where b = this
|
||
// with angle \theta such that \theta(b) - \pi < \theta < \theta(b)
|
||
// New edge for rays emanating from b->source() where b = this
|
||
// with angle \theta such that \theta(b) - \pi < \theta < \theta(b)
|
||
set_target_cusp_edge(v,new Edge);
|
||
set_source_cusp_edge(v,new Edge);
|
||
target_cusp_edge(v)->set_sign(false);
|
||
set_sup(target_cusp_edge(v),v);
|
||
set_inf(target_cusp_edge(v),v->pi());
|
||
source_cusp_edge(v)->set_sign(true);
|
||
set_sup(source_cusp_edge(v),v);
|
||
set_inf(source_cusp_edge(v),v->pi());
|
||
// -------------------------------------------------------------------------
|
||
// New face directed from b->target_object() to b, the sink is b
|
||
Face_handle f0 = new Face;
|
||
set_sup(f0,v);
|
||
set_inf(f0,v->pi());
|
||
f0->set_top_edge(target_cusp_edge(v));
|
||
if (is_xx_left(v)) set_adjacent_faces(target_cusp_edge(v),f0,0,0);
|
||
else set_adjacent_faces(target_cusp_edge(v),0,f0,0);
|
||
// New face directed from b->source_object() to b, the sink is b
|
||
Face_handle f1 = new Face;
|
||
set_sup(f1,v);
|
||
set_inf(f1,v->pi());
|
||
f1->set_bottom_edge(source_cusp_edge(v));
|
||
if (is_left_xx(v)) set_adjacent_faces(source_cusp_edge(v),0,0,f1);
|
||
else set_adjacent_faces(source_cusp_edge(v),0,f1,0);
|
||
// -------------------------------------------------------------------------
|
||
set_sup(v,fs); set_inf(v,fi);
|
||
set_sup(v->pi(),pifs); set_inf(v->pi(),pifi);
|
||
// -------------------------------------------------------------------------
|
||
// Do the same with b->pi()
|
||
//if (!v->pi()->is_constraint()) set_constraint(v->pi());
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::remove_constraint(Vertex_handle v)
|
||
{
|
||
if (!v->is_constraint()) return;
|
||
// -------------------------------------------------------------------------
|
||
// erase(v->target_cusp_edge());
|
||
// erase(v->source_cusp_edge());
|
||
unset_constraint(v);
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::add_constraint(Vertex_handle v)
|
||
{
|
||
if (v->is_constraint()) return;
|
||
// -------------------------------------------------------------------------
|
||
set_constraint(v);
|
||
set_constraint(v->pi());
|
||
//push_back(*v->target_cusp_edge());
|
||
//push_back(*v->source_cusp_edge());
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::unset_constraint(Vertex_handle v)
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
delete v->target_cusp_face(); delete v->source_cusp_face();
|
||
delete v->target_cusp_edge(); delete v->source_cusp_edge();
|
||
// if (v->pi()->is_constraint()) unset_constraint(v->pi());
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
sweep_regular(const Vertex_handle& v, const _Tr&) const
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// The operators used by this method
|
||
typename _Tr::Sup sup; typename _Tr::Inf inf;
|
||
typename _Tr::Set_inf set_inf;
|
||
typename _Tr::Set_adjacent_faces_one_to_one set_adjacent_faces;
|
||
typename _Tr::Dl dl; typename _Tr::Dr dr;
|
||
typename _Tr::Ul ul; typename _Tr::Ur ur;
|
||
typename _Tr::Is_left_xx is_left_xx;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
// -------------------------------------------------------------------------
|
||
// The four edges adjacent to v
|
||
Edge_handle e = cw_source_edge(v);
|
||
Edge_handle ep = ccw_source_edge(v);
|
||
Edge_handle f = cw_target_edge(v);
|
||
Edge_handle fp = ccw_target_edge(v);
|
||
// -------------------------------------------------------------------------
|
||
// The six faces adjacent to v.
|
||
Face_handle f0,f1,f2,f3;
|
||
if (e->sign()) { f0 = ul(e); f1 = dl(e); }
|
||
else {
|
||
f0 = dl(e); if (f0 == 0 || sup(f0) == v) f0 = dl(f);
|
||
f1 = dr(e);
|
||
}
|
||
if (f->sign()) {
|
||
f2 = ur(f); if (f2 == 0 || sup(f2) == v) f2 = ur(e);
|
||
f3 = ul(f);
|
||
}
|
||
else { f2 = dr(f); f3 = ul(f); }
|
||
Face_handle f4 = sup(v); set_inf(f4,v);
|
||
Face_handle f5 = inf(v);
|
||
// -------------------------------------------------------------------------
|
||
// Due to our identification pi^2(v) == v, a face can appear twice in the
|
||
// antichain. As a consequence a face can appear twice in the antichain.
|
||
// This implies that the pointers Edge <---> Face are not necessarily
|
||
// reversible.
|
||
// Our solution: make the Edge --> Face pointers correct and use the
|
||
// infinite face and the two Edges below.
|
||
Edge_handle botf4 = f4->bottom_edge();
|
||
Edge_handle topf4 = f4->top_edge();
|
||
// -------------------------------------------------------------------------
|
||
// Updating the Edge <--> Face pointers for the two new edges of the
|
||
// antichain.
|
||
if (linear_space() && !is_on_convex_hull(v)) {
|
||
set_adjacent_faces(e,0,0,0);
|
||
set_adjacent_faces(f,0,0,0);
|
||
}
|
||
if (is_left_xx(v)) set_adjacent_faces(ep,f4,f3,f0);
|
||
else set_adjacent_faces(ep,f0,f4,f3);
|
||
set_adjacent_faces(fp,f1,f2,f4);
|
||
// -------------------------------------------------------------------------
|
||
// Fix the pointers due to the problem mentionned above. This only occurs
|
||
// for faces whose sink are on the convex-hull.
|
||
CGAL_precondition(f4 != 0);
|
||
CGAL_precondition(f5 != 0);
|
||
if (is_on_convex_hull(v)) {
|
||
if (f2 == f4) { f4->set_top_edge(ep); f4->set_bottom_edge(fp); }
|
||
else {
|
||
Face_handle w = (is_left_xx(v)) ? f2 : f0;
|
||
if (botf4 != 0 && w->bottom_edge() != botf4)
|
||
f4->set_bottom_edge(botf4);
|
||
if (topf4 != 0 && w->top_edge() != topf4)
|
||
f4->set_top_edge(topf4);
|
||
}
|
||
if (f5->bottom_edge() != e) {
|
||
f5->set_top_edge(infinite_face()->bottom_edge());
|
||
return;
|
||
}
|
||
else if (f5->top_edge() != f) {
|
||
f5->set_bottom_edge(infinite_face()->top_edge());
|
||
return;
|
||
}
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// The face inf(v) is no longer swept.
|
||
f5->set_bottom_edge(0);
|
||
f5->set_top_edge (0);
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
void
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
sweep_constraint(const Vertex_handle& v, const _Tr&) const
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
// The operators used by this method
|
||
typename _Tr::Sup sup;
|
||
typename _Tr::Set_adjacent_faces set_adjacent_old_faces;
|
||
typename _Tr::Set_adjacent_faces_one_to_one set_adjacent_faces;
|
||
typename _Tr::Dl dl; typename _Tr::Dr dr;
|
||
typename _Tr::Ul ul; typename _Tr::Ur ur;
|
||
typename _Tr::Target_cusp_face target_cusp_face;
|
||
typename _Tr::Source_cusp_face source_cusp_face;
|
||
typename _Tr::Is_left_xx is_left_xx; typename _Tr::Is_xx_left is_xx_left;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
// -------------------------------------------------------------------------
|
||
// The four edges adjacent to v
|
||
Edge_handle e = cw_source_edge(v);
|
||
Edge_handle ep = ccw_source_edge(v);
|
||
Edge_handle f = cw_target_edge(v);
|
||
Edge_handle fp = ccw_target_edge(v);
|
||
// -------------------------------------------------------------------------
|
||
// The four regular faces adjacent to v
|
||
Face_handle f0,f1,f2,f3;
|
||
if (e->sign()) { f0 = ul(e); f1 = dl(e); }
|
||
else { f0 = dl(e); if (sup(f0) == v) f0 = dl(f); f1 = dr(e); }
|
||
if (f->sign()) { f2 = ur(f); if (sup(f2) == v) f2 = ur(e); f3 = ul(f); }
|
||
else { f2 = dr(f); f3 = ul(f); }
|
||
// -------------------------------------------------------------------------
|
||
// The four degenerate faces adjacent to v
|
||
Face_handle a = source_cusp_face(v);
|
||
Face_handle ap = source_cusp_face(v->pi());
|
||
Face_handle b = target_cusp_face(v);
|
||
Face_handle bp = target_cusp_face(v->pi());
|
||
// -------------------------------------------------------------------------
|
||
Edge_handle fix = 0;
|
||
if (is_on_convex_hull(v)) {
|
||
if (e->sign() && e != f2->bottom_edge()) fix = f2->bottom_edge();
|
||
else if (!e->sign() && f != f0->top_edge()) fix = f0->top_edge();
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Updating the Edge <--> Face pointers for the two new edges of the
|
||
// antichain.
|
||
typename Vertex::Type_util type;
|
||
switch (type(is_left_xx(v),is_xx_left(v))) {
|
||
case Vertex::LL:
|
||
set_adjacent_old_faces(e,f1,f2,f0);
|
||
set_adjacent_old_faces(f,a,b,f3);
|
||
set_adjacent_faces(ep,ap,f3,bp);
|
||
set_adjacent_faces(fp,f1,f2,f0);
|
||
break;
|
||
case Vertex::RR:
|
||
set_adjacent_old_faces(e,a,f1,b);
|
||
set_adjacent_old_faces(f,f0,f2,f3);
|
||
set_adjacent_faces(ep,f0,f2,f3);
|
||
set_adjacent_faces(fp,f1,ap,bp);
|
||
break;
|
||
case Vertex::LR:
|
||
set_adjacent_old_faces(e,f1,b,f0);
|
||
set_adjacent_old_faces(f,a,f2,f3);
|
||
set_adjacent_faces(ep,f2,f3,bp);
|
||
set_adjacent_faces(fp,f1,ap,f0);
|
||
break;
|
||
case Vertex::RL:
|
||
set_adjacent_old_faces(e,a,f1,f2);
|
||
set_adjacent_old_faces(f,f0,b,f3);
|
||
set_adjacent_faces(ep,f0,ap,f3);
|
||
set_adjacent_faces(fp,f1,f2,bp);
|
||
break;
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
if (is_on_convex_hull(v) && fix != 0) {
|
||
if (fix->sign()) set_adjacent_faces(fix,dl(fix),ur(fix),ul(fix));
|
||
else set_adjacent_faces(fix,dl(fix),dr(fix),ul(fix));
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
if (a != 0) a->set_top_edge(0);
|
||
if (b != 0) b->set_bottom_edge(0);
|
||
// -------------------------------------------------------------------------
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_swept_regular(const Vertex_handle& v, _Tr /*tr*/) const
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
CGAL_precondition(!v->is_constraint());
|
||
// -------------------------------------------------------------------------
|
||
// The operators used by this method
|
||
typename _Tr::Sup sup;
|
||
typename _Tr::Dl dl; typename _Tr::Dr dr;
|
||
typename _Tr::Ul ul; typename _Tr::Ur ur;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
typename _Tr::Is_left_xx is_left_xx; typename _Tr::Is_xx_left is_xx_left;
|
||
// -------------------------------------------------------------------------
|
||
// A vertex v has been swept iff. the two following conditions are
|
||
// satisfied:
|
||
// (1) sup(v) is not 0
|
||
// (2) the faces adjacent to ccw_source_edge(v) and ccw_target_edge(v) are
|
||
// correct. We check this with the help of the faces adjacent to
|
||
// cw_source_edge(v) and cw_target_edge(v) which are assumed to be correct.
|
||
// -------------------------------------------------------------------------
|
||
// Checking (1).
|
||
Face_handle f4 = sup(v);
|
||
if (f4 == 0) return false;
|
||
// -------------------------------------------------------------------------
|
||
// Checking (2).
|
||
// -------------------------------------------------------------------------
|
||
// The four edges adjacent to v
|
||
Edge_handle e = cw_source_edge(v);
|
||
Edge_handle ep = ccw_source_edge(v);
|
||
Edge_handle f = cw_target_edge(v);
|
||
Edge_handle fp = ccw_target_edge(v);
|
||
if (e == 0 || ep == 0 || f == 0 || fp == 0) return false;
|
||
// -------------------------------------------------------------------------
|
||
// The remaining faces adjacent to v different from inf(v).
|
||
Face_handle f0,f1,f2,f3;
|
||
if (e->sign()) { f0 = ul(e); f1 = dl(e); }
|
||
else {
|
||
f0 = dl(e); if (f0 == 0 || sup(f0) == v) f0 = dl(f);
|
||
f1 = dr(e);
|
||
}
|
||
if (f->sign()) {
|
||
f2 = ur(f); if (f2 == 0 || sup(f2) == v) f2 = ur(e);
|
||
f3 = ul(f);
|
||
}
|
||
else { f2 = dr(f); f3 = ul(f); }
|
||
// -------------------------------------------------------------------------
|
||
if (is_left_xx(v)) {
|
||
if (f4 != dl(ep) || f3 != ur(ep) || f0 != ul(ep)) return false;
|
||
}
|
||
else {
|
||
if (f0 != dl(ep) || f4 != dr(ep) || f3 != ul(ep)) return false;
|
||
}
|
||
if (is_xx_left(v)) {
|
||
if (f1 != dl(fp) || f2 != ur(fp) || f4 != ul(fp)) return false;
|
||
}
|
||
else {
|
||
if (f1 != dl(fp) || f2 != dr(fp) || f4 != ul(fp)) return false;
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
return true;
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_swept_constraint(const Vertex_handle& v, _Tr /*tr*/) const
|
||
{
|
||
// -------------------------------------------------------------------------
|
||
CGAL_precondition(v->is_constraint());
|
||
// -------------------------------------------------------------------------
|
||
// The operators used by this method
|
||
typename _Tr::Sup sup;
|
||
typename _Tr::Dl dl; typename _Tr::Dr dr;
|
||
typename _Tr::Ul ul; typename _Tr::Ur ur;
|
||
typename _Tr::Cw_source_edge cw_source_edge;
|
||
typename _Tr::Cw_target_edge cw_target_edge;
|
||
typename _Tr::Ccw_source_edge ccw_source_edge;
|
||
typename _Tr::Ccw_target_edge ccw_target_edge;
|
||
typename _Tr::Target_cusp_face target_cusp_face;
|
||
typename _Tr::Source_cusp_face source_cusp_face;
|
||
typename _Tr::Is_left_xx is_left_xx; typename _Tr::Is_xx_left is_xx_left;
|
||
// -------------------------------------------------------------------------
|
||
// See is_swept_regular for the criterion. As sup(v) is not defined we check
|
||
// only point (2).
|
||
// -------------------------------------------------------------------------
|
||
// The four edges adjacent to v
|
||
Edge_handle e = cw_source_edge(v);
|
||
Edge_handle ep = ccw_source_edge(v);
|
||
Edge_handle f = cw_target_edge(v);
|
||
Edge_handle fp = ccw_target_edge(v);
|
||
if (e == 0 || ep == 0 || f == 0 || fp == 0) return false;
|
||
// -------------------------------------------------------------------------
|
||
// The four regular faces adjacent to v
|
||
Face_handle f0,f1,f2,f3;
|
||
if (e->sign()) {
|
||
if (ul(e) == 0 || ur(e) == 0) return false;
|
||
f0 = ul(e); f1 = dl(e);
|
||
}
|
||
else {
|
||
if (dl(e) == 0 || dr(e) == 0) return false;
|
||
f0 = dl(e); if (sup(f0) == v) f0 = dl(f); f1 = dr(e);
|
||
}
|
||
if (f->sign()) {
|
||
if (ul(f) == 0 || ur(f) == 0) return false;
|
||
f2 = ur(f); if (sup(f2) == v) f2 = ur(e); f3 = ul(f);
|
||
}
|
||
else {
|
||
if (dl(f) == 0 || dr(f) == 0) return false;
|
||
f2 = dr(f); f3 = ul(f);
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// The four degenerate faces adjacent to v
|
||
Face_handle a = source_cusp_face(v);
|
||
Face_handle b = target_cusp_face(v);
|
||
Face_handle ap = source_cusp_face(v->pi());
|
||
Face_handle bp = target_cusp_face(v->pi());
|
||
if (a == 0 || b == 0 || ap == 0 || bp == 0) return false;
|
||
// -------------------------------------------------------------------------
|
||
// Updating the Edge <--> Face pointers for the two new edges of the
|
||
// antichain.
|
||
typename Vertex::Type_util type;
|
||
switch (type(is_left_xx(v),is_xx_left(v))) {
|
||
case Vertex::LL:
|
||
if (ap != dl(ep) || f3 != ur(ep) || bp != ul(ep)) return false;
|
||
if (f1 != dl(fp) || f2 != ur(fp) || f0 != ul(fp)) return false;
|
||
break;
|
||
case Vertex::RR:
|
||
if (f0 != dl(ep) || f2 != dr(ep) || f3 != ul(ep)) return false;
|
||
if (f1 != dl(fp) || ap != dr(fp) || bp != ul(fp)) return false;
|
||
break;
|
||
case Vertex::LR:
|
||
if (f2 != dl(ep) || f3 != ur(ep) || bp != ul(ep)) return false;
|
||
if (f1 != dl(fp) || ap != dr(fp) || f0 != ul(fp)) return false;
|
||
break;
|
||
case Vertex::RL:
|
||
if (f0 != dl(ep) || ap != dr(ep) || f3 != ul(ep)) return false;
|
||
if (f1 != dl(fp) || f2 != ur(fp) || bp != ul(fp)) return false;
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
template < class _Gtr , class It , class Flip >
|
||
template < class _Tr>
|
||
bool
|
||
Visibility_complex_antichain<_Gtr,It,Flip>::
|
||
is_swept(const Vertex_handle& v, _Tr tr) const
|
||
{
|
||
if (!v->is_constraint()) return is_swept_regular(v,tr);
|
||
return (is_swept_constraint(v,tr) && is_swept_constraint(v->pi(),tr));
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------
|
||
|
||
CGAL_END_NAMESPACE
|
||
|
||
#endif
|