You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
6.1 KiB
210 lines
6.1 KiB
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|
* |
|
* This library is open source and may be redistributed and/or modified under |
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|
* (at your option) any later version. The full license is in LICENSE file |
|
* included with this distribution, and on the openscenegraph.org website. |
|
* |
|
* This library is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* OpenSceneGraph Public License for more details. |
|
*/ |
|
|
|
#ifndef OSGUTIL_EDGECOLLECTOR |
|
#define OSGUTIL_EDGECOLLECTOR 1 |
|
|
|
|
|
#include <set> |
|
#include <map> |
|
#include <list> |
|
#include <vector> |
|
#include <algorithm> |
|
|
|
#include <osg/Array> |
|
#include <osg/Geometry> |
|
#include <osg/ref_ptr> |
|
|
|
#include <osgUtil/Export> |
|
|
|
|
|
namespace osgUtil { |
|
|
|
struct dereference_less |
|
{ |
|
template<class T, class U> |
|
inline bool operator() (const T& lhs,const U& rhs) const |
|
{ |
|
return *lhs < *rhs; |
|
} |
|
}; |
|
|
|
template<class T> |
|
bool dereference_check_less(const T& lhs,const T& rhs) |
|
{ |
|
if (lhs==rhs) return false; |
|
if (!lhs) return true; |
|
if (!rhs) return false; |
|
return *lhs < *rhs; |
|
} |
|
|
|
struct dereference_clear |
|
{ |
|
template<class T> |
|
inline void operator() (const T& t) |
|
{ |
|
T& non_const_t = const_cast<T&>(t); |
|
non_const_t->clear(); |
|
} |
|
}; |
|
|
|
|
|
class OSGUTIL_EXPORT EdgeCollector |
|
{ |
|
public: |
|
|
|
struct Triangle; |
|
struct Edge; |
|
struct Edgeloop; |
|
struct Point; |
|
|
|
typedef std::list<osg::ref_ptr<osg::UIntArray> > IndexArrayList; |
|
|
|
~EdgeCollector(); |
|
|
|
void setGeometry(osg::Geometry* geometry); |
|
osg::Geometry* getGeometry() { return _geometry; } |
|
|
|
unsigned int getNumOfTriangles() { return _triangleSet.size(); } |
|
|
|
typedef std::set<osg::ref_ptr<Edge>,dereference_less > EdgeSet; |
|
typedef std::vector<osg::ref_ptr<Edge> > EdgeList; |
|
typedef std::list< osg::ref_ptr<Edgeloop> > EdgeloopList; |
|
typedef std::set< osg::ref_ptr<Point>,dereference_less > PointSet; |
|
typedef std::vector< osg::ref_ptr<Point> > PointList; |
|
typedef std::list< osg::ref_ptr<Triangle> > TriangleList; |
|
typedef std::set< osg::ref_ptr<Triangle> > TriangleSet; |
|
typedef std::map< osg::ref_ptr<Triangle>, unsigned int, dereference_less > TriangleMap; |
|
|
|
struct OSGUTIL_EXPORT Point : public osg::Referenced |
|
{ |
|
Point(): _protected(false), _index(0) {} |
|
|
|
bool _protected; |
|
|
|
unsigned int _index; |
|
|
|
osg::Vec3d _vertex; |
|
TriangleSet _triangles; |
|
|
|
void clear() { _triangles.clear(); } |
|
|
|
bool operator < ( const Point& rhs) const { return _vertex < rhs._vertex; } |
|
|
|
bool isBoundaryPoint() const; |
|
}; |
|
|
|
struct OSGUTIL_EXPORT Edge : public osg::Referenced |
|
{ |
|
void clear(); |
|
|
|
osg::ref_ptr<Point> _p1; |
|
osg::ref_ptr<Point> _p2; |
|
|
|
osg::ref_ptr<Point> _op1; |
|
osg::ref_ptr<Point> _op2; |
|
|
|
TriangleSet _triangles; |
|
|
|
|
|
bool operator < ( const Edge& rhs) const; |
|
|
|
bool operator == ( const Edge& rhs) const; |
|
|
|
bool operator != ( const Edge& rhs) const; |
|
|
|
void setOrderedPoints(Point* p1, Point* p2); |
|
|
|
void addTriangle(Triangle* triangle) { _triangles.insert(triangle); } |
|
|
|
bool isBoundaryEdge() const { return _triangles.size()<=1; } |
|
|
|
bool isAdjacentToBoundary() const { return isBoundaryEdge() || _p1->isBoundaryPoint() || _p2->isBoundaryPoint(); } |
|
|
|
bool endConnected(const Edge& rhs) const { return (_op2 == rhs._op1); } |
|
|
|
bool beginConnected(const Edge& rhs) const { return (_op1 == rhs._op2); } |
|
}; |
|
|
|
struct OSGUTIL_EXPORT Triangle : public osg::Referenced |
|
{ |
|
Triangle() {} |
|
|
|
void clear(); |
|
|
|
bool operator < (const Triangle& rhs) const; |
|
|
|
void setOrderedPoints(Point* p1, Point* p2, Point* p3); |
|
|
|
float distance(const osg::Vec3& vertex) const { return _plane.distance(vertex); } |
|
|
|
bool isBoundaryTriangle() const |
|
{ return (_e1->isBoundaryEdge() || _e2->isBoundaryEdge() || _e3->isBoundaryEdge()); } |
|
|
|
|
|
osg::ref_ptr<Point> _p1; |
|
osg::ref_ptr<Point> _p2; |
|
osg::ref_ptr<Point> _p3; |
|
|
|
osg::ref_ptr<Point> _op1; |
|
osg::ref_ptr<Point> _op2; |
|
osg::ref_ptr<Point> _op3; |
|
|
|
osg::ref_ptr<Edge> _e1; |
|
osg::ref_ptr<Edge> _e2; |
|
osg::ref_ptr<Edge> _e3; |
|
|
|
osg::Plane _plane; |
|
}; |
|
|
|
struct OSGUTIL_EXPORT Edgeloop : public osg::Referenced |
|
{ |
|
typedef std::vector<osg::ref_ptr<Edge> > EdgeList; |
|
|
|
bool isClosed() { return (_edgeList.back()->endConnected(*_edgeList.front().get())); } |
|
|
|
osg::UIntArray * toIndexArray() const; |
|
|
|
EdgeList _edgeList; |
|
}; |
|
|
|
|
|
|
|
Triangle* addTriangle(unsigned int p1, unsigned int p2, unsigned int p3); |
|
Triangle* addTriangle(Point* p1, Point* p2, Point* p3); |
|
|
|
Edge* addEdge(Triangle* triangle, Point* p1, Point* p2); |
|
|
|
Point* addPoint(Triangle* triangle, unsigned int p1) { return addPoint(triangle,_originalPointList[p1].get()); } |
|
Point* addPoint(Triangle* triangle, Point* point); |
|
|
|
void getBoundaryEdgeList(EdgeList & el); |
|
bool extractBoundaryEdgeloop(EdgeList & el, Edgeloop & edgeloop); |
|
bool extractBoundaryEdgeloopList(EdgeList & el, EdgeloopList & edgeloopList); |
|
|
|
void getEdgeloopIndexList(IndexArrayList & ial); |
|
|
|
//protected: |
|
|
|
osg::Geometry* _geometry; |
|
|
|
EdgeSet _edgeSet; |
|
TriangleSet _triangleSet; |
|
PointSet _pointSet; |
|
PointList _originalPointList; |
|
|
|
}; |
|
|
|
} // end of osgUtil namespace |
|
|
|
#endif // ** OSGUTIL_EDGECOLLECTOR ** //
|
|
|