cgal/Nef_2/include/CGAL/Nef_2/PM_persistent_PL.h

209 lines
6.7 KiB
C++

// Copyright (c) 1997-2000 Max-Planck-Institute Saarbruecken (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// 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$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
#ifndef CGAL_PM_PERSISTENT_PL_H
#define CGAL_PM_PERSISTENT_PL_H
#include <CGAL/license/Nef_2.h>
#include <CGAL/Nef_2/gen_point_location.h>
template <typename PMPL>
struct PM_persistent_PL_traits
{
typedef PMPL Graph;
typedef typename PMPL::Vertex_const_handle Node;
typedef typename PMPL::Halfedge_const_handle Edge;
typedef typename PMPL::Face_const_handle Face;
typedef typename PMPL::Object_handle Object_handle;
typedef typename PMPL::Geometry Geometry;
typedef typename PMPL::Point Point;
typedef typename PMPL::Segment Segment;
const Geometry* pK;
typedef typename PMPL::Vertex_const_iterator NodeIterator;
NodeIterator Nodes_begin(const Graph& G) const { return G.vertices_begin(); }
NodeIterator Nodes_end(const Graph& G) const { return G.vertices_end(); }
Node toNode(const NodeIterator& nit) const { return nit; }
typedef typename PMPL::Halfedge_around_vertex_const_circulator HAVC;
struct IncEdgeIterator {
HAVC _start, _curr;
bool met;
IncEdgeIterator() {}
IncEdgeIterator(HAVC c) :
_start(c), _curr(c), met(false) {}
IncEdgeIterator& operator++()
{ if (_curr==_start)
if (!met) { met=true; ++_curr; }
else { _curr=HAVC(); }
else ++_curr;
return *this;
}
bool operator==(const IncEdgeIterator& it2) const
{ return _curr==it2._curr; }
bool operator!=(const IncEdgeIterator& it2) const
{ return !(*this==it2); }
};
Edge toEdge(const IncEdgeIterator& eit) const { return eit._curr; }
IncEdgeIterator IncEdges_begin(const Graph& G, const Node& n)
{ return IncEdgeIterator(HAVC(G.first_out_edge(n))); }
IncEdgeIterator IncEdges_end(const Graph& G, const Node& n)
{ return IncEdgeIterator(); }
enum EdgeCategory
{ StartingNonVertical, StartingVertical, EndingNonVertical, EndingVertical };
Node opposite(const Graph& G, const Edge& e, const Node& u)
{ if ( G.source(e) == u ) return G.target(e);
else return G.source(e); }
EdgeCategory ClassifyEdge(const Graph& G, const Edge& e, const Node& u)
{
Point p_u = G.point(u);
Point p_v = G.point(opposite(G,e,u));
int cmpX = pK->compare_x(p_u, p_v);
if ( cmpX < 0 ) return StartingNonVertical;
if ( cmpX > 0 ) return EndingNonVertical;
int cmpY = pK->compare_y(p_u, p_v);
CGAL_assertion(cmpY != 0);
if ( cmpY < 0 ) return StartingVertical;
return EndingVertical;
}
typedef Point XCoord;
const XCoord getXCoord(const Point& p) const
{ return p; }
const XCoord getXCoord(const Graph& G, const Node& n) const
{ return G.point(n); }
class PredLessThanX {
const Geometry* pK;
public:
PredLessThanX() : pK(0) {}
PredLessThanX(const Geometry* pKi) : pK(pKi) {}
PredLessThanX(const PredLessThanX& P) : pK(P.pK)
{ CGAL_NEF_TRACEN("copy PredLessThanX"); }
int operator() (const XCoord& x1, const XCoord& x2) const
{ return pK->compare_x(x1,x2) < 0; }
};
PredLessThanX getLessThanX() const { return PredLessThanX(pK); }
// Curve connected functionality:
typedef Segment Curve;
Curve makeCurve(const Point& p) const
{ return pK->construct_segment(p,p); }
Curve makeCurve(const Graph& G, const Node& n) const
{ return makeCurve(G.point(n)); }
Curve makeCurve(const Graph& G, const Edge& e) const
{ Point ps = G.point(G.source(e)), pt = G.point(G.target(e));
Curve res(G.point(G.source(e)),G.point(G.target(e)));
if ( pK->compare_xy(ps,pt) < 0 ) res = pK->construct_segment(ps,pt);
else res = pK->construct_segment(pt,ps);
return res;
}
struct PredCompareCurves {
const Geometry* pK;
PredCompareCurves() : pK(0) {}
PredCompareCurves(const Geometry* pKi) : pK(pKi) {}
PredCompareCurves(const PredCompareCurves& P) : pK(P.pK) {}
int cmppntseg(const Point& p, const Curve& s) const
{
if ( pK->compare_x(pK->source(s),pK->target(s)) != 0 ) // !vertical
return pK->orientation(pK->source(s),pK->target(s), p);
if ( pK->compare_y(p,pK->source(s)) <= 0 ) return -1;
if ( pK->compare_y(p,pK->target(s)) >= 0 ) return +1;
return 0;
}
int operator()(const Curve& s1, const Curve& s2) const
{
Point a = pK->source(s1);
Point b = pK->target(s1);
Point c = pK->source(s2);
Point d = pK->target(s2);
if ( a==b )
if ( c==d ) return pK->compare_y(a,c);
else return cmppntseg(a, s2);
if ( c==d ) return -cmppntseg(c, s1);
// now both are non-trivial:
int cmpX = pK->compare_x(a, c);
if ( cmpX < 0 )
return - pK->orientation(a,b,c);
if ( cmpX > 0 )
return pK->orientation(c,d,a);
int cmpY = pK->compare_y(a, c);
if ( cmpY < 0 ) return -1;
if ( cmpY > 0 ) return +1;
// cmpX == cmpY == 0 => a == c
return pK->orientation(c,d,b);
}
};
PredCompareCurves getCompareCurves() const
{ return PredCompareCurves(pK); }
typedef GenericLocation<Node, Edge> Location;
typedef Object_handle QueryResult;
virtual Object_handle
PostProcess(const Location& L, const Location& L_plus,
const Point& p) const
{ /* we only get an L_plus (non-nil) if L is ABOVE a vertex
in which case we want to extract the face from the edge
below (p+epsilon) available via L_plus. */
if (!L_plus.is_nil()) { CGAL_assertion(L_plus.is_edge());
return Object_handle(Edge(L_plus));
} else {
if ( L.is_edge() ) {
return Object_handle(Edge(L));
}
if ( L.is_node() ) {
Node v(L); CGAL_assertion( v != Node() );
return Object_handle(v);
}
return Object_handle();
}
}
PM_persistent_PL_traits() : pK(0) {}
PM_persistent_PL_traits(const Geometry& k) : pK(&k) {}
virtual ~PM_persistent_PL_traits() {}
virtual void sweep_begin(const Graph&) {}
virtual void sweep_moveto(const XCoord&) {}
virtual void sweep_end() {}
virtual void clear() {}
};
#endif // CGAL_PM_PM_PERSISTENT_PL_H