mirror of https://github.com/CGAL/cgal
389 lines
14 KiB
C++
389 lines
14 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.
|
|
//
|
|
// $Source: /CVSROOT/CGAL/Packages/Visibility_complex/include/CGAL/Visibility_complex_2.h,v $
|
|
// $Revision$ $Date$
|
|
// $Name: $
|
|
//
|
|
// Author(s) : Pierre Angelier, Michel Pocchiola
|
|
|
|
|
|
#ifndef CGAL_VISIBILITY_COMPLEX_2_H
|
|
#define CGAL_VISIBILITY_COMPLEX_2_H
|
|
|
|
#include <CGAL/Visibility_complex_2/Antichain.h>
|
|
#include <CGAL/Visibility_complex_2/iterators.h>
|
|
#include <CGAL/Visibility_complex_2/Items.h>
|
|
#include <CGAL/Visibility_complex_2/Matroidal_items.h>
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <functional>
|
|
#include <vector>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template < class Tr ,
|
|
class It = Visibility_complex_2_items ,
|
|
class Flip = Visibility_complex_2_details::Flip_traits>
|
|
class Visibility_complex_2
|
|
{
|
|
public:
|
|
|
|
typedef Tr Gt;
|
|
typedef Visibility_complex_2<Tr,It,Flip> Self;
|
|
typedef Visibility_complex_2_details::Antichain<Tr,It,Flip> Antichain;
|
|
typedef typename Antichain::Disk_handle Disk_handle;
|
|
typedef typename Antichain::Disk Disk;
|
|
|
|
typedef typename Antichain::Vertex Vertex;
|
|
typedef typename Antichain::Vertex_handle Vertex_handle;
|
|
typedef typename Antichain::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Antichain::Edge Edge;
|
|
typedef typename Antichain::Edge_handle Edge_handle;
|
|
typedef typename Antichain::Edge_const_handle Edge_const_handle;
|
|
typedef typename Antichain::Face Face;
|
|
typedef typename Antichain::Face_handle Face_handle;
|
|
typedef typename Antichain::Face_const_handle Face_const_handle;
|
|
typedef typename Antichain::Bitangent_2 Bitangent_2;
|
|
|
|
typedef typename Antichain::Ccw_traits Ccw_traits;
|
|
typedef typename Antichain::Cw_traits Cw_traits;
|
|
|
|
private:
|
|
typedef Visibility_complex_2_details::Iterator_base<Self,
|
|
typename std::vector<Vertex_handle>::const_iterator,
|
|
Vertex*> Iterator_base;
|
|
typedef Visibility_complex_2_details::Iterator_base<Self,
|
|
typename std::vector<Vertex_handle>::const_iterator,
|
|
const Vertex*,Iterator_base> Const_iterator_base;
|
|
public:
|
|
typedef Visibility_complex_2_details::Vertex_iterator<Iterator_base,
|
|
Vertex,Vertex&,Vertex*>
|
|
Vertex_iterator;
|
|
typedef Visibility_complex_2_details::Vertex_iterator<Const_iterator_base,
|
|
Vertex,const Vertex&,const Vertex*,
|
|
Vertex_iterator>
|
|
Vertex_const_iterator;
|
|
|
|
typedef Visibility_complex_2_details::Edge_iterator<Iterator_base,
|
|
Edge,Edge&,Edge*>
|
|
Edge_iterator;
|
|
typedef Visibility_complex_2_details::Edge_iterator<Const_iterator_base,
|
|
Edge,const Edge&,const Edge*,Edge_iterator>
|
|
Edge_const_iterator;
|
|
|
|
typedef Visibility_complex_2_details::Face_iterator<Iterator_base,
|
|
Face,Face&,Face*>
|
|
Face_iterator;
|
|
typedef Visibility_complex_2_details::Face_iterator<Const_iterator_base,
|
|
Face,const Face&,const Face*,Face_iterator>
|
|
Face_const_iterator;
|
|
// -------------------------------------------------------------------------
|
|
typedef typename Antichain::Linear_sweep_iterator Linear_sweep_iterator;
|
|
typedef typename Antichain::Linear_sweep_const_iterator
|
|
Linear_sweep_const_iterator;
|
|
typedef typename Antichain::Sweep_iterator Sweep_iterator;
|
|
typedef typename Antichain::Sweep_const_iterator Sweep_const_iterator;
|
|
|
|
typedef typename Antichain::Constraint_input Constraint_input;
|
|
typedef typename std::vector<Disk>::iterator Disk_iterator;
|
|
typedef typename Antichain::Constraint_iterator Constraint_iterator;
|
|
typedef typename std::vector<Disk>::const_iterator Disk_const_iterator;
|
|
typedef typename Antichain::Constraint_const_iterator
|
|
Constraint_const_iterator;
|
|
private:
|
|
class Rep {
|
|
|
|
Edge_iterator edges_begin() { return Edge_iterator(vertices.begin()); }
|
|
Edge_iterator edges_end() { return Edge_iterator(vertices.end()); }
|
|
Face_iterator faces_begin() { return Face_iterator(vertices.begin()); }
|
|
Face_iterator faces_end() { return Face_iterator(vertices.end()); }
|
|
Vertex_iterator vertices_begin() {
|
|
return Vertex_iterator(vertices.begin());
|
|
}
|
|
Vertex_iterator vertices_end() {
|
|
return Vertex_iterator(vertices.end());
|
|
}
|
|
|
|
public:
|
|
std::vector<Disk> disks;
|
|
Antichain antichain;
|
|
std::vector<Vertex_handle> vertices;
|
|
typedef std::map<Disk_handle,Edge_handle> EM;
|
|
EM pos;
|
|
EM neg;
|
|
Rep() :
|
|
antichain(), vertices() {};
|
|
template <class DiskIterator , class ConstraintIterator> Rep
|
|
(DiskIterator first, DiskIterator last,
|
|
ConstraintIterator firstc,ConstraintIterator lastc) {
|
|
std::copy(first,last,std::back_inserter(disks));
|
|
antichain.~Antichain();
|
|
// This is awfull, but an antichain cannot be copied, and I cannot
|
|
// initialise it in the base clause, because disks would have to be
|
|
// initialised there too, which breaks Sun CC
|
|
new (&antichain) Antichain(false,disks.begin(),disks.end(),firstc,lastc);
|
|
for (typename Antichain::Edge_iterator e=antichain.edges_begin();
|
|
e!=antichain.edges_end();++e) {
|
|
if (e->object()&&e->sign()) {
|
|
pos.insert(typename EM::value_type(e->object(),&*e));
|
|
} else {
|
|
neg.insert(typename EM::value_type(e->object(),&*e));
|
|
}
|
|
}
|
|
}
|
|
~Rep() {
|
|
for (Face_iterator i=faces_begin(); i!=faces_end();++i) {
|
|
delete(i.operator ->());
|
|
}
|
|
for (Edge_iterator i=edges_begin(); i!=edges_end();++i) {
|
|
if (i->object()) delete(i.operator ->());
|
|
}
|
|
delete antichain.infinite_face();
|
|
for (typename std::vector<Vertex_handle>::iterator i=vertices.begin();
|
|
i!=vertices.end();++i) {
|
|
if (!(*i)->is_constraint()) {
|
|
delete (*i)->pi();
|
|
delete *i;
|
|
}
|
|
}
|
|
for (Constraint_iterator i=antichain.constraints_begin();
|
|
i!=antichain.constraints_end();++i) {
|
|
delete i->pi()->source_cusp_edge();
|
|
delete i->pi()->target_cusp_edge();
|
|
delete i->pi();
|
|
delete i->source_cusp_edge();
|
|
delete i->target_cusp_edge();
|
|
}
|
|
}
|
|
};
|
|
boost::shared_ptr<Rep> ptr;
|
|
public:
|
|
// -------------------------------------------------------------------------
|
|
Visibility_complex_2() { }
|
|
template <class DiskIterator , class ConstraintIterator>
|
|
Visibility_complex_2(DiskIterator first, DiskIterator last,
|
|
ConstraintIterator firstc,ConstraintIterator lastc);
|
|
template <class DiskIterator>
|
|
Visibility_complex_2(DiskIterator first, DiskIterator last)
|
|
{
|
|
std::vector<Constraint_input> L;
|
|
*this = Visibility_complex_2(first,last,L.begin(),L.end());
|
|
}
|
|
Visibility_complex_2(const Visibility_complex_2& vc) : ptr(vc.ptr) {}
|
|
|
|
int size() const { return 2*ptr->vertices.size(); }
|
|
|
|
Face_handle infinite_face() {
|
|
return ptr->antichain.infinite_face();
|
|
}
|
|
Face_const_handle infinite_face() const {
|
|
return ptr->antichain.infinite_face();
|
|
}
|
|
|
|
bool is_on_convex_hull(Vertex_handle v) const
|
|
{ return ptr->antichain.is_on_convex_hull(v); }
|
|
|
|
Vertex_iterator vertices_begin()
|
|
{ return Vertex_iterator(ptr->vertices.begin()); }
|
|
Vertex_const_iterator vertices_begin() const
|
|
{ return Vertex_iterator(ptr->vertices.begin()); }
|
|
Vertex_iterator vertices_end()
|
|
{ return Vertex_iterator(ptr->vertices.end()); }
|
|
Vertex_const_iterator vertices_end() const
|
|
{ return Vertex_iterator(ptr->vertices.end()); }
|
|
// -------------------------------------------------------------------------
|
|
Edge_iterator edges_begin() { return Edge_iterator(ptr->vertices.begin()); }
|
|
Edge_const_iterator edges_begin() const
|
|
{ return Edge_iterator(ptr->vertices.begin()); }
|
|
Edge_iterator edges_end() { return Edge_iterator(ptr->vertices.end()); }
|
|
Edge_const_iterator edges_end() const
|
|
{ return Edge_iterator(ptr->vertices.end()); }
|
|
// -------------------------------------------------------------------------
|
|
Face_iterator faces_begin() { return Face_iterator(ptr->vertices.begin()); }
|
|
Face_const_iterator faces_begin() const
|
|
{ return Face_iterator(ptr->vertices.begin()); }
|
|
Face_iterator faces_end() { return Face_iterator(ptr->vertices.end()); }
|
|
Face_const_iterator faces_end() const
|
|
{ return Face_iterator(ptr->vertices.end()); }
|
|
|
|
Disk_iterator disks_begin() {
|
|
return ptr->disks.begin();
|
|
}
|
|
Disk_iterator disks_end() {
|
|
return ptr->disks.end();
|
|
}
|
|
Constraint_iterator constraints_begin() {
|
|
return ptr->antichain.constraints_begin();
|
|
}
|
|
Constraint_iterator constraints_end() {
|
|
return ptr->antichain.constraints_end();
|
|
}
|
|
Disk_const_iterator disks_begin() const {
|
|
return ptr->disks.begin();
|
|
}
|
|
Disk_const_iterator disks_end() const {
|
|
return ptr->disks.end();
|
|
}
|
|
Constraint_const_iterator constraints_begin() const {
|
|
return ptr->antichain.constraints_begin();
|
|
}
|
|
Constraint_const_iterator constraints_end() const {
|
|
return ptr->antichain.constraints_end();
|
|
}
|
|
|
|
Edge_handle positive_edge(const Disk&d) {
|
|
return ptr->pos[&d];
|
|
}
|
|
Edge_handle negative_edge(const Disk& d) {
|
|
return ptr->neg[&d];
|
|
}
|
|
|
|
Edge_const_handle positive_edge(const Disk&d) const {
|
|
return ptr->pos[&d];
|
|
}
|
|
Edge_const_handle negative_edge(const Disk& d) const {
|
|
return ptr->neg[&d];
|
|
}
|
|
|
|
Antichain * antichain() {
|
|
return &(ptr->antichain);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
template < class Gtr_ , class It , class Flip >
|
|
template < class DiskIterator , class ConstraintIterator >
|
|
Visibility_complex_2<Gtr_,It,Flip>::Visibility_complex_2(
|
|
DiskIterator first, DiskIterator last ,
|
|
ConstraintIterator firstc,ConstraintIterator lastc) :
|
|
ptr(new Rep(first,last,firstc,lastc))
|
|
{
|
|
Sweep_iterator v(&(ptr->antichain)) , vend(&(ptr->antichain),0);
|
|
for ( ; v != vend ; ++v) {
|
|
ptr->vertices.push_back(&(*v));
|
|
}
|
|
}
|
|
|
|
template <class GeomTraits,
|
|
class Items=Visibility_complex_2_details::Items,
|
|
class Flip=Visibility_complex_2_details::Flip_traits>
|
|
class Compute_free_bitangents_2 {
|
|
|
|
typedef Visibility_complex_2_details::Antichain<GeomTraits,Items,Flip>
|
|
Antichain;
|
|
|
|
typedef typename Antichain::Constraint_iterator Constraint_iterator;
|
|
typedef typename Antichain::Edge Edge;
|
|
typedef typename Antichain::Edge_handle Edge_handle;
|
|
typedef typename Antichain::Face Face;
|
|
typedef typename Antichain::Face_handle Face_handle;
|
|
typedef typename Antichain::Vertex Vertex;
|
|
typedef typename Antichain::Vertex_handle Vertex_handle;
|
|
typedef typename Antichain::Disk Disk;
|
|
typedef typename Antichain::Disk_handle Disk_handle;
|
|
public:
|
|
typedef typename Antichain::Bitangent_2 Bitangent_2;
|
|
typedef typename Antichain::Constraint_input Constraint_input;
|
|
typedef GeomTraits Gt;
|
|
|
|
template <class DiskIterator, class OutputIterator>
|
|
OutputIterator operator()
|
|
(DiskIterator first, DiskIterator last,OutputIterator out) const {
|
|
std::vector<Constraint_input> L;
|
|
return operator()(first,last,L.begin(),L.end(),out);
|
|
}
|
|
|
|
template <class DiskIterator, class ConstraintIterator, class OutputIterator>
|
|
OutputIterator operator()
|
|
(DiskIterator first, DiskIterator last,
|
|
ConstraintIterator firstc, ConstraintIterator lastc,
|
|
OutputIterator out) const {
|
|
Antichain a(true,first,last,firstc,lastc);
|
|
typedef typename Antichain::Sweep_iterator Sweep_iterator;
|
|
Sweep_iterator v(&a) , vend(&a,0);
|
|
while (v!=vend) {
|
|
*out=static_cast<Bitangent_2&>(*v);
|
|
++out;
|
|
++v;
|
|
}
|
|
struct explore {
|
|
std::set<Edge_handle> edges;
|
|
std::set<Face_handle> faces;
|
|
std::set<Vertex_handle> vertices;
|
|
|
|
void meet(Face_handle f) {
|
|
if (!f||!faces.insert(f).second) return;
|
|
meet(f->inf());
|
|
meet(f->sup());
|
|
meet(f->bottom_edge());
|
|
meet(f->top_edge());
|
|
}
|
|
void meet(Edge_handle e) {
|
|
if (!e||!edges.insert(e).second) return;
|
|
meet(e->inf());
|
|
meet(e->sup());
|
|
meet(e->dl());
|
|
meet(e->dr());
|
|
meet(e->ul());
|
|
meet(e->ur());
|
|
}
|
|
void meet(Vertex_handle v) {
|
|
if (!v||!vertices.insert(v).second) return;
|
|
meet(v->raw_pi());
|
|
meet(v->inf());
|
|
meet(v->sup());
|
|
meet(v->ccw_source_edge());
|
|
meet(v->ccw_target_edge());
|
|
meet(v->cw_target_edge());
|
|
meet(v->cw_source_edge());
|
|
meet(v->target_cusp_edge());
|
|
meet(v->source_cusp_edge());
|
|
}
|
|
};
|
|
explore expl;
|
|
expl.meet(&*a.edges_begin());
|
|
|
|
for (typename std::set<Face_handle>::iterator i=expl.faces.begin();
|
|
i!=expl.faces.end();i++) {
|
|
if (*i!=a.infinite_face()) delete *i;
|
|
}
|
|
for (typename std::set<Edge_handle>::iterator i=expl.edges.begin();
|
|
i!=expl.edges.end();i++) {
|
|
if ((*i)->object()) delete *i;
|
|
}
|
|
delete a.infinite_face();
|
|
for (typename std::set<Vertex_handle>::iterator i=expl.vertices.begin();
|
|
i!=expl.vertices.end();i++) {
|
|
if (!(*i)->is_constraint()) delete *i;
|
|
}
|
|
for (Constraint_iterator i=a.constraints_begin();
|
|
i!=a.constraints_end();++i) {
|
|
delete i->pi()->source_cusp_edge();
|
|
delete i->pi()->target_cusp_edge();
|
|
delete i->source_cusp_edge();
|
|
delete i->target_cusp_edge();
|
|
delete i->pi();
|
|
}
|
|
return out;
|
|
}
|
|
};
|
|
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_VISIBILITY_COMPLEX_2_H
|