Added support for removing triangles and associated edge and points from

the EdgeCollapse object.
This commit is contained in:
Robert Osfield
2004-04-13 15:59:30 +00:00
parent 073e49c3d8
commit 025cc6b819

View File

@@ -62,6 +62,7 @@ public:
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;
struct Point : public osg::Referenced
{
@@ -71,7 +72,7 @@ public:
osg::Vec3 _vertex;
FloatList _attributes;
TriangleList _triangles;
TriangleSet _triangles;
bool operator < ( const Point& rhs) const
{
@@ -152,8 +153,6 @@ public:
};
Triangle* addTriangle(unsigned int p1, unsigned int p2, unsigned int p3)
{
//std::cout<<"addTriangle("<<p1<<","<<p2<<","<<p3<<")"<<std::endl;
@@ -182,12 +181,24 @@ public:
triangle->_e2 = addEdge(triangle, triangle->_p2.get(), triangle->_p3.get());
triangle->_e3 = addEdge(triangle, triangle->_p3.get(), triangle->_p1.get());
_triangleList.push_back(triangle);
_triangleSet.insert(triangle);
return triangle;
}
void removeTriangle(Triangle* triangle)
{
removePoint(triangle,triangle->_p1.get());
removePoint(triangle,triangle->_p2.get());
removePoint(triangle,triangle->_p3.get());
removeEdge(triangle,triangle->_e1.get());
removeEdge(triangle,triangle->_e2.get());
removeEdge(triangle,triangle->_e3.get());
_triangleSet.erase(triangle);
}
Edge* addEdge(Triangle* triangle, Point* p1, Point* p2)
{
//std::cout<<"addEdge("<<p1<<","<<p2<<")"<<std::endl;
@@ -217,7 +228,26 @@ public:
edge->addTriangle(triangle);
return 0;
return edge.get();
}
void removeEdge(Triangle* triangle, Edge* edge)
{
EdgeSet::iterator itr = _edgeSet.find(edge);
if (itr!=_edgeSet.end())
{
if (edge->_t1==triangle) edge->_t1 = 0;
if (edge->_t2==triangle) edge->_t2 = 0;
if (!edge->_t1.valid() && !edge->_t2.valid())
{
edge->_p1 = 0;
edge->_p2 = 0;
// edge no longer in use, so need to delete.
_edgeSet.erase(itr);
}
}
}
Point* addPoint(Triangle* triangle, unsigned int p1)
@@ -225,15 +255,6 @@ public:
osg::ref_ptr<Point> point = _originalPointList[p1];
#if 0
point->_index = p1;
if (_vertexList.valid() && p1<_vertexList->size())
{
point->_vertex = (*_vertexList)[p1];
}
#endif
PointSet::iterator itr = _pointSet.find(point);
if (itr==_pointSet.end())
{
@@ -246,11 +267,27 @@ public:
//std::cout<<" reusePoint("<<point.get()<<")"<<std::endl;
}
point->_triangles.push_back(triangle);
point->_triangles.insert(triangle);
return point.get();
}
void removePoint(Triangle* triangle, Point* point)
{
PointSet::iterator itr = _pointSet.find(point);
if (itr!=_pointSet.end())
{
point->_triangles.erase(triangle);
if (point->_triangles.empty())
{
// point no longer in use, so need to delete.
_pointSet.erase(itr);
}
}
}
protected:
typedef std::vector< osg::ref_ptr<osg::Array> > ArrayList;
@@ -260,7 +297,7 @@ protected:
unsigned int _targetNumTriangles;
EdgeSet _edgeSet;
TriangleList _triangleList;
TriangleSet _triangleSet;
PointSet _pointSet;
PointList _originalPointList;
@@ -607,6 +644,39 @@ class CopyPointsToVertexArrayVisitor : public osg::ArrayVisitor
void EdgeCollapse::copyBackToGeometry()
{
{
TriangleList toDelete;
float sampleRatio = 0.1;
unsigned int numAccepted = 0;
unsigned int numDeleted = 0;
for(TriangleSet::iterator titr=_triangleSet.begin();
titr!=_triangleSet.end();
++titr)
{
float r = (numAccepted>0) ? (float)numAccepted / (float)(numAccepted+numDeleted) : 0.0f;
if (r>sampleRatio)
{
Triangle* triangle = const_cast<Triangle*>((*titr).get());
toDelete.push_back(triangle);
++numDeleted;
}
else
{
++numAccepted;
}
}
for(TriangleList::iterator ditr=toDelete.begin();
ditr!=toDelete.end();
++ditr)
{
Triangle* triangle = const_cast<Triangle*>((*ditr).get());
removeTriangle(triangle);
//_triangleSet.erase(triangle);
}
}
// rebuild the _pointList from the _pointSet
_originalPointList.clear();
std::copy(_pointSet.begin(),_pointSet.end(),std::back_inserter(_originalPointList));
@@ -642,13 +712,13 @@ void EdgeCollapse::copyBackToGeometry()
_geometry->getVertexAttribArray(vi)->accept(copyArrayToPoints);
}
osg::DrawElementsUInt* primitives = new osg::DrawElementsUInt(GL_TRIANGLES,_triangleList.size()*3);
osg::DrawElementsUInt* primitives = new osg::DrawElementsUInt(GL_TRIANGLES,_triangleSet.size()*3);
unsigned int pos = 0;
for(TriangleList::iterator titr=_triangleList.begin();
titr!=_triangleList.end();
for(TriangleSet::iterator titr=_triangleSet.begin();
titr!=_triangleSet.end();
++titr)
{
Triangle* triangle = (*titr).get();
const Triangle* triangle = (*titr).get();
(*primitives)[pos++] = triangle->_p1->_index;
(*primitives)[pos++] = triangle->_p2->_index;
(*primitives)[pos++] = triangle->_p3->_index;