Further work on simplifier edge collapse code
This commit is contained in:
@@ -38,6 +38,11 @@ class EdgeCollapse
|
||||
{
|
||||
public:
|
||||
|
||||
struct Triangle;
|
||||
struct Edge;
|
||||
struct Point;
|
||||
|
||||
|
||||
EdgeCollapse():
|
||||
_targetNumTriangles(0) {}
|
||||
~EdgeCollapse() {}
|
||||
@@ -49,14 +54,48 @@ public:
|
||||
|
||||
unsigned int getNumOfTriangles() { return 0; }
|
||||
|
||||
bool collapseMinimumErrorEdge() { return false; }
|
||||
Point* computeNewPoint(Edge* edge,float r=0.5) const
|
||||
{
|
||||
Point* point = new Point;
|
||||
float r1 = 1.0f-r;
|
||||
float r2 = r;
|
||||
Point* p1 = edge->_p1.get();
|
||||
Point* p2 = edge->_p2.get();
|
||||
point->_vertex = p1->_vertex * r1 + p2->_vertex * r2;
|
||||
unsigned int s = osg::minimum(p1->_attributes.size(),p2->_attributes.size());
|
||||
for(unsigned int i=0;i<s;++i)
|
||||
{
|
||||
point->_attributes.push_back(p1->_attributes[i]*r1 + p2->_attributes[i]*r2);
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
bool collapseMinimumErrorEdge()
|
||||
{
|
||||
// std::cout<<"collapseMinimumErrorEdge"<<std::endl;
|
||||
if (!_edgeSet.empty())
|
||||
{
|
||||
for(EdgeSet::iterator itr=_edgeSet.begin();
|
||||
itr!=_edgeSet.end();
|
||||
++itr)
|
||||
{
|
||||
// std::cout<<" Trying edge collapse"<<std::endl;
|
||||
Edge* edge = const_cast<Edge*>(itr->get());
|
||||
//if (collapseEdge(edge,edge->_p1.get())) return true;
|
||||
if (!edge->isAdjacentToBoundary())
|
||||
{
|
||||
osg::ref_ptr<Point> pNew = computeNewPoint(edge);
|
||||
|
||||
if (collapseEdge(edge,pNew.get())) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void copyBackToGeometry();
|
||||
|
||||
struct Triangle;
|
||||
struct Edge;
|
||||
struct Point;
|
||||
|
||||
typedef std::vector<float> FloatList;
|
||||
typedef std::set<osg::ref_ptr<Edge>,dereference_less> EdgeSet;
|
||||
typedef std::set< osg::ref_ptr<Point>,dereference_less> PointSet;
|
||||
@@ -81,7 +120,22 @@ public:
|
||||
|
||||
return _attributes < rhs._attributes;
|
||||
}
|
||||
|
||||
|
||||
bool isBoundaryPoint() const
|
||||
{
|
||||
for(TriangleSet::iterator itr=_triangles.begin();
|
||||
itr!=_triangles.end();
|
||||
++itr)
|
||||
{
|
||||
const Triangle* triangle = itr->get();
|
||||
if ((triangle->_e1->_p1==this || triangle->_e1->_p2==this) && triangle->_e1->isBoundaryEdge()) return true;
|
||||
if ((triangle->_e2->_p1==this || triangle->_e2->_p2==this) && triangle->_e2->isBoundaryEdge()) return true;
|
||||
if ((triangle->_e3->_p1==this || triangle->_e3->_p2==this) && triangle->_e3->isBoundaryEdge()) return true;
|
||||
|
||||
//if ((*itr)->isBoundaryTriangle()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -92,8 +146,7 @@ public:
|
||||
osg::ref_ptr<Point> _p1;
|
||||
osg::ref_ptr<Point> _p2;
|
||||
|
||||
osg::ref_ptr<Triangle> _t1;
|
||||
osg::ref_ptr<Triangle> _t2;
|
||||
TriangleSet _triangles;
|
||||
|
||||
bool _needToRecomputeErrorMetric;
|
||||
float _errorMetric;
|
||||
@@ -113,7 +166,7 @@ public:
|
||||
if (getErrorMetric()<rhs.getErrorMetric()) return true;
|
||||
else if (rhs.getErrorMetric()>getErrorMetric()) return false;
|
||||
}
|
||||
|
||||
|
||||
if (_p1 < rhs._p1) return true;
|
||||
if (rhs._p1 < _p1) return false;
|
||||
|
||||
@@ -122,18 +175,18 @@ public:
|
||||
|
||||
void addTriangle(Triangle* triangle)
|
||||
{
|
||||
if (!_t1)
|
||||
{
|
||||
_t1 = triangle;
|
||||
}
|
||||
else if (!_t2)
|
||||
{
|
||||
_t2 = triangle;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Warning too many traingles sharing edge"<<std::endl;
|
||||
}
|
||||
_triangles.insert(triangle);
|
||||
if (_triangles.size()>2) osg::notify(osg::NOTICE)<<"Warning too many traingles ("<<_triangles.size()<<") sharing edge "<<std::endl;
|
||||
}
|
||||
|
||||
bool isBoundaryEdge() const
|
||||
{
|
||||
return _triangles.size()<=1;
|
||||
}
|
||||
|
||||
bool isAdjacentToBoundary() const
|
||||
{
|
||||
return isBoundaryEdge() || _p1->isBoundaryPoint() || _p2->isBoundaryPoint();
|
||||
}
|
||||
|
||||
};
|
||||
@@ -160,6 +213,11 @@ public:
|
||||
osg::ref_ptr<Edge> _e1;
|
||||
osg::ref_ptr<Edge> _e2;
|
||||
osg::ref_ptr<Edge> _e3;
|
||||
|
||||
bool isBoundaryTriangle() const
|
||||
{
|
||||
return (_e1->isBoundaryEdge() || _e2->isBoundaryEdge() || _e3->isBoundaryEdge());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -196,6 +254,37 @@ public:
|
||||
return triangle;
|
||||
}
|
||||
|
||||
Triangle* addTriangle(Point* p1, Point* p2, Point* p3)
|
||||
{
|
||||
// detect if triangle is degenerate.
|
||||
if (p1==p2 || p2==p3 || p1==p3) return 0;
|
||||
|
||||
Triangle* triangle = new Triangle;
|
||||
|
||||
Point* points[3];
|
||||
points[0] = addPoint(triangle, p1);
|
||||
points[1] = addPoint(triangle, p2);
|
||||
points[2] = addPoint(triangle, p3);
|
||||
|
||||
// find the lowest value point in the list.
|
||||
unsigned int lowest = 0;
|
||||
if (points[1]<points[lowest]) lowest = 1;
|
||||
if (points[2]<points[lowest]) lowest = 2;
|
||||
|
||||
|
||||
triangle->_p1 = points[lowest];
|
||||
triangle->_p2 = points[(lowest+1)%3];
|
||||
triangle->_p3 = points[(lowest+2)%3];
|
||||
|
||||
triangle->_e1 = addEdge(triangle, triangle->_p1.get(), triangle->_p2.get());
|
||||
triangle->_e2 = addEdge(triangle, triangle->_p2.get(), triangle->_p3.get());
|
||||
triangle->_e3 = addEdge(triangle, triangle->_p3.get(), triangle->_p1.get());
|
||||
|
||||
_triangleSet.insert(triangle);
|
||||
|
||||
return triangle;
|
||||
}
|
||||
|
||||
void removeTriangle(Triangle* triangle)
|
||||
{
|
||||
if (triangle->_p1.valid()) removePoint(triangle,triangle->_p1.get());
|
||||
@@ -232,41 +321,60 @@ public:
|
||||
|
||||
}
|
||||
|
||||
bool testTriangle(Triangle* triangle)
|
||||
unsigned int testTriangle(Triangle* triangle)
|
||||
{
|
||||
bool result = true;
|
||||
unsigned int result = 0;
|
||||
if (!(triangle->_p1))
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p1==NULL"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
else if (triangle->_p1->_triangles.count(triangle)==0)
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p1->_triangles does not contain triangle"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
|
||||
if (!(triangle->_p2))
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p2==NULL"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
else if (triangle->_p2->_triangles.count(triangle)==0)
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p2->_triangles does not contain triangle"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
|
||||
if (!(triangle->_p3))
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p3==NULL"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
else if (triangle->_p3->_triangles.count(triangle)==0)
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _p3->_triangles does not contain triangle"<<std::endl;
|
||||
result = false;
|
||||
++result;
|
||||
}
|
||||
|
||||
if (testEdge(triangle->_e1.get()))
|
||||
{
|
||||
++result;
|
||||
std::cout<<"testTriangle("<<triangle<<") _e1 test failed"<<std::endl;
|
||||
}
|
||||
|
||||
if (testEdge(triangle->_e2.get()))
|
||||
{
|
||||
++result;
|
||||
std::cout<<"testTriangle("<<triangle<<") _e2 test failed"<<std::endl;
|
||||
}
|
||||
|
||||
if (testEdge(triangle->_e3.get()))
|
||||
{
|
||||
std::cout<<"testTriangle("<<triangle<<") _e3 test failed"<<std::endl;
|
||||
++result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -277,10 +385,7 @@ public:
|
||||
itr!=_triangleSet.end();
|
||||
++itr)
|
||||
{
|
||||
if (!testTriangle(const_cast<Triangle*>(itr->get())))
|
||||
{
|
||||
++numErrors;
|
||||
}
|
||||
numErrors += testTriangle(const_cast<Triangle*>(itr->get()));
|
||||
}
|
||||
return numErrors;
|
||||
}
|
||||
@@ -322,16 +427,14 @@ public:
|
||||
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->_triangles.erase(triangle);
|
||||
if (edge->_triangles.empty())
|
||||
{
|
||||
edge->_p1 = 0;
|
||||
edge->_p2 = 0;
|
||||
|
||||
// edge no longer in use, so need to delete.
|
||||
_edgeSet.erase(itr);
|
||||
|
||||
edge->_p1 = 0;
|
||||
edge->_p2 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -380,75 +483,111 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void collapseEdge(Edge* edge, Point* pNew)
|
||||
|
||||
bool collapseEdge(Edge* edge, Point* pNew)
|
||||
{
|
||||
if (!edge->_t1.valid() || !edge->_t2.valid()) return;
|
||||
if (edge->_triangles.size()<2) return false;
|
||||
|
||||
osg::ref_ptr<Edge> keep_edge_locally_referenced_to_prevent_premature_deletion = edge;
|
||||
osg::ref_ptr<Point> keep_point_locally_referenced_to_prevent_premature_deletion = pNew;
|
||||
|
||||
if (edge->_p1 != pNew)
|
||||
osg::ref_ptr<Point> edge_p1 = edge->_p1;
|
||||
osg::ref_ptr<Point> edge_p2 = edge->_p2;
|
||||
|
||||
TriangleList triangles_p1;
|
||||
TriangleList triangles_p2;
|
||||
|
||||
if (edge_p1 != pNew)
|
||||
{
|
||||
TriangleSet triangles_p1 = edge->_p1->_triangles;
|
||||
triangles_p1.erase(edge->_t1.get());
|
||||
triangles_p1.erase(edge->_t2.get());
|
||||
for(TriangleSet::iterator titr_p1 = triangles_p1.begin();
|
||||
titr_p1 != triangles_p1.end();
|
||||
++titr_p1)
|
||||
for(TriangleSet::iterator itr=edge_p1->_triangles.begin();
|
||||
itr!=edge_p1->_triangles.end();
|
||||
++itr)
|
||||
{
|
||||
replaceTrianglePoint(const_cast<Triangle*>(titr_p1->get()),edge->_p1.get(),pNew);
|
||||
if (edge->_triangles.count(*itr)==0) triangles_p1.push_back(const_cast<Triangle*>(itr->get()));
|
||||
}
|
||||
|
||||
//triangles_p1 = edge_p1->_triangles;
|
||||
}
|
||||
|
||||
if (edge->_p2 != pNew)
|
||||
if (edge_p2 != pNew)
|
||||
{
|
||||
TriangleSet triangles_p2 = edge->_p2->_triangles;
|
||||
triangles_p2.erase(edge->_t1.get());
|
||||
triangles_p2.erase(edge->_t2.get());
|
||||
for(TriangleSet::iterator titr_p2 = triangles_p2.begin();
|
||||
titr_p2 != triangles_p2.end();
|
||||
++titr_p2)
|
||||
for(TriangleSet::iterator itr=edge_p2->_triangles.begin();
|
||||
itr!=edge_p2->_triangles.end();
|
||||
++itr)
|
||||
{
|
||||
replaceTrianglePoint(const_cast<Triangle*>(titr_p2->get()),edge->_p2.get(),pNew);
|
||||
if (edge->_triangles.count(*itr)==0) triangles_p2.push_back(const_cast<Triangle*>(itr->get()));
|
||||
}
|
||||
//triangles_p2 = edge_p2->_triangles;
|
||||
}
|
||||
#if 1
|
||||
osg::ref_ptr<Triangle> t1 = edge->_t1;
|
||||
osg::ref_ptr<Triangle> t2 = edge->_t1;
|
||||
|
||||
// remove triangles directly connected to edge
|
||||
if (edge->_t1.valid()) removeTriangle(edge->_t1.get());
|
||||
if (edge->_t2.valid()) removeTriangle(edge->_t2.get());
|
||||
#endif
|
||||
for(TriangleList::iterator titr_p1 = triangles_p1.begin();
|
||||
titr_p1 != triangles_p1.end();
|
||||
++titr_p1)
|
||||
{
|
||||
removeTriangle(const_cast<Triangle*>(titr_p1->get()));
|
||||
}
|
||||
|
||||
for(TriangleList::iterator titr_p2 = triangles_p2.begin();
|
||||
titr_p2 != triangles_p2.end();
|
||||
++titr_p2)
|
||||
{
|
||||
removeTriangle(const_cast<Triangle*>(titr_p2->get()));
|
||||
}
|
||||
|
||||
for(TriangleList::iterator titr_p1 = triangles_p1.begin();
|
||||
titr_p1 != triangles_p1.end();
|
||||
++titr_p1)
|
||||
{
|
||||
Triangle* triangle = const_cast<Triangle*>(titr_p1->get());
|
||||
Point* p1 = (triangle->_p1==edge_p1 || triangle->_p1==edge_p2)? pNew : triangle->_p1.get();
|
||||
Point* p2 = (triangle->_p2==edge_p1 || triangle->_p2==edge_p2)? pNew : triangle->_p2.get();
|
||||
Point* p3 = (triangle->_p3==edge_p1 || triangle->_p3==edge_p2)? pNew : triangle->_p3.get();
|
||||
addTriangle(p1,p2,p3);
|
||||
}
|
||||
|
||||
for(TriangleList::iterator titr_p2 = triangles_p2.begin();
|
||||
titr_p2 != triangles_p2.end();
|
||||
++titr_p2)
|
||||
{
|
||||
Triangle* triangle = const_cast<Triangle*>(titr_p2->get());
|
||||
Point* p1 = (triangle->_p1==edge_p1 || triangle->_p1==edge_p2)? pNew : triangle->_p1.get();
|
||||
Point* p2 = (triangle->_p2==edge_p1 || triangle->_p2==edge_p2)? pNew : triangle->_p2.get();
|
||||
Point* p3 = (triangle->_p3==edge_p1 || triangle->_p3==edge_p2)? pNew : triangle->_p3.get();
|
||||
addTriangle(p1,p2,p3);
|
||||
}
|
||||
|
||||
for(TriangleSet::iterator teitr=edge->_triangles.begin();
|
||||
teitr!=edge->_triangles.end();
|
||||
++teitr)
|
||||
{
|
||||
removeTriangle(const_cast<Triangle*>(teitr->get()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
unsigned int testEdge(Edge* edge)
|
||||
{
|
||||
unsigned int numErrors = 0;
|
||||
if (edge->_t1.valid())
|
||||
for(TriangleSet::iterator teitr=edge->_triangles.begin();
|
||||
teitr!=edge->_triangles.end();
|
||||
++teitr)
|
||||
{
|
||||
if (!(edge->_t1->_e1 == edge || edge->_t1->_e2 == edge || edge->_t1->_e3 == edge))
|
||||
Triangle* triangle = const_cast<Triangle*>(teitr->get());
|
||||
if (!(triangle->_e1 == edge || triangle->_e2 == edge || triangle->_e3 == edge))
|
||||
{
|
||||
std::cout<<"testEdge("<<edge<<")._t1 != point back to this edge"<<std::endl;
|
||||
std::cout<<" _t1->_e1=="<<edge->_t1->_e1.get()<<std::endl;
|
||||
std::cout<<" _t1->_e2=="<<edge->_t1->_e2.get()<<std::endl;
|
||||
std::cout<<" _t1->_e3=="<<edge->_t1->_e3.get()<<std::endl;
|
||||
++numErrors;
|
||||
}
|
||||
}
|
||||
if (edge->_t2.valid())
|
||||
{
|
||||
if (!(edge->_t2->_e1 == edge || edge->_t2->_e2 == edge || edge->_t2->_e3 == edge))
|
||||
{
|
||||
std::cout<<"testEdge("<<edge<<")._t2 != point back to this edge"<<std::endl;
|
||||
std::cout<<" _t2->_e1=="<<edge->_t2->_e1.get()<<std::endl;
|
||||
std::cout<<" _t2->_e2=="<<edge->_t2->_e2.get()<<std::endl;
|
||||
std::cout<<" _t2->_e3=="<<edge->_t2->_e3.get()<<std::endl;
|
||||
std::cout<<"testEdge("<<edge<<"). triangle != point back to this edge"<<std::endl;
|
||||
std::cout<<" triangle->_e1=="<<triangle->_e1.get()<<std::endl;
|
||||
std::cout<<" triangle->_e2=="<<triangle->_e2.get()<<std::endl;
|
||||
std::cout<<" triangle->_e3=="<<triangle->_e3.get()<<std::endl;
|
||||
++numErrors;
|
||||
}
|
||||
}
|
||||
|
||||
if (edge->_triangles.empty())
|
||||
{
|
||||
std::cout<<"testEdge("<<edge<<")._triangles is empty"<<std::endl;
|
||||
++numErrors;
|
||||
}
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
@@ -464,6 +603,18 @@ public:
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
unsigned int computeNumBoundaryEdges()
|
||||
{
|
||||
unsigned int numBoundaryEdges = 0;
|
||||
for(EdgeSet::iterator itr = _edgeSet.begin();
|
||||
itr!=_edgeSet.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)->isBoundaryEdge()) ++numBoundaryEdges;
|
||||
}
|
||||
return numBoundaryEdges;
|
||||
}
|
||||
|
||||
|
||||
Point* addPoint(Triangle* triangle, unsigned int p1)
|
||||
{
|
||||
@@ -779,8 +930,11 @@ class CopyPointsToArrayVisitor : public osg::ArrayVisitor
|
||||
|
||||
for(unsigned int i=0;i<_pointList.size();++i)
|
||||
{
|
||||
float val = (_pointList[i]->_attributes[_index]);
|
||||
array[i] = R (val);
|
||||
if (_index<_pointList[i]->_attributes.size())
|
||||
{
|
||||
float val = (_pointList[i]->_attributes[_index]);
|
||||
array[i] = R (val);
|
||||
}
|
||||
}
|
||||
|
||||
++_index;
|
||||
@@ -817,7 +971,7 @@ class CopyPointsToArrayVisitor : public osg::ArrayVisitor
|
||||
for(unsigned int i=0;i<_pointList.size();++i)
|
||||
{
|
||||
EdgeCollapse::FloatList& attributes = _pointList[i]->_attributes;
|
||||
array[i].set(attributes[_index],attributes[_index+1]);
|
||||
if (_index+1<attributes.size()) array[i].set(attributes[_index],attributes[_index+1]);
|
||||
}
|
||||
_index += 2;
|
||||
}
|
||||
@@ -829,7 +983,7 @@ class CopyPointsToArrayVisitor : public osg::ArrayVisitor
|
||||
for(unsigned int i=0;i<_pointList.size();++i)
|
||||
{
|
||||
EdgeCollapse::FloatList& attributes = _pointList[i]->_attributes;
|
||||
array[i].set(attributes[_index],attributes[_index+1],attributes[_index+2]);
|
||||
if (_index+2<attributes.size()) array[i].set(attributes[_index],attributes[_index+1],attributes[_index+2]);
|
||||
}
|
||||
_index += 3;
|
||||
}
|
||||
@@ -841,7 +995,7 @@ class CopyPointsToArrayVisitor : public osg::ArrayVisitor
|
||||
for(unsigned int i=0;i<_pointList.size();++i)
|
||||
{
|
||||
EdgeCollapse::FloatList& attributes = _pointList[i]->_attributes;
|
||||
array[i].set(attributes[_index],attributes[_index+1],attributes[_index+2],attributes[_index+3]);
|
||||
if (_index+3<attributes.size()) array[i].set(attributes[_index],attributes[_index+1],attributes[_index+2],attributes[_index+3]);
|
||||
}
|
||||
_index += 4;
|
||||
}
|
||||
@@ -896,82 +1050,41 @@ class CopyPointsToVertexArrayVisitor : public osg::ArrayVisitor
|
||||
|
||||
void EdgeCollapse::copyBackToGeometry()
|
||||
{
|
||||
|
||||
std::cout<<"******* BEFORE EDGE COLLAPSE ********"<<_triangleSet.size()<<std::endl;
|
||||
|
||||
std::cout<<"Number of triangle errors before edge collapse= "<<testAllTriangles()<<std::endl;
|
||||
std::cout<<"Number of edge errors before edge collapse= "<<testAllEdges()<<std::endl;
|
||||
std::cout<<"Number of point errors before edge collapse= "<<testAllPoints()<<std::endl;
|
||||
std::cout<<"Number of triangles= "<<_triangleSet.size()<<std::endl;
|
||||
std::cout<<"Number of points= "<<_pointSet.size()<<std::endl;
|
||||
std::cout<<"Number of edges= "<<_edgeSet.size()<<std::endl;
|
||||
std::cout<<"Number of boundary edges= "<<computeNumBoundaryEdges()<<std::endl;
|
||||
|
||||
#if 1
|
||||
|
||||
float sampleRatio = 0.8;
|
||||
unsigned int targetNumEdges = (unsigned int)((float)_edgeSet.size()*sampleRatio);
|
||||
while (_edgeSet.size()>targetNumEdges)
|
||||
{
|
||||
float sampleRatio = 0.8;
|
||||
unsigned int numAccepted = 0;
|
||||
unsigned int numDeleted = 0;
|
||||
typedef std::vector< osg::ref_ptr<Edge> > EdgeList;
|
||||
EdgeList toDelete;
|
||||
for(EdgeSet::iterator eitr=_edgeSet.begin();
|
||||
eitr!=_edgeSet.end();
|
||||
++eitr)
|
||||
unsigned int numBefore = computeNumBoundaryEdges();
|
||||
bool result = collapseMinimumErrorEdge();
|
||||
unsigned int numAfter = computeNumBoundaryEdges();
|
||||
if (numBefore!=numAfter)
|
||||
{
|
||||
float r = (numAccepted>0) ? (float)numAccepted / (float)(numAccepted+numDeleted) : 0.0f;
|
||||
if (r>sampleRatio)
|
||||
{
|
||||
Edge* edge = const_cast<Edge*>(eitr->get());
|
||||
toDelete.push_back(edge);
|
||||
++numDeleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
++numAccepted;
|
||||
}
|
||||
std::cout<<"After collapse edge, boundary edges changes from "<<numBefore<<" to "<<numAfter<<std::endl;
|
||||
}
|
||||
if (!result) break;
|
||||
}
|
||||
|
||||
for(EdgeList::iterator ditr=toDelete.begin();
|
||||
ditr!=toDelete.end();
|
||||
++ditr)
|
||||
{
|
||||
Edge* edge = const_cast<Edge*>(ditr->get());
|
||||
collapseEdge(edge, edge->_p1.get());
|
||||
}
|
||||
}
|
||||
|
||||
std::cout<<"Number of errors after edge collapse= "<<testAllTriangles()<<std::endl;
|
||||
std::cout<<"******* AFTER EDGE COLLAPSE *********"<<_triangleSet.size()<<std::endl;
|
||||
|
||||
std::cout<<"Number of triangle errors after edge collapse= "<<testAllTriangles()<<std::endl;
|
||||
std::cout<<"Number of edge errors before edge collapse= "<<testAllEdges()<<std::endl;
|
||||
std::cout<<"Number of point errors after edge collapse= "<<testAllPoints()<<std::endl;
|
||||
|
||||
#else
|
||||
// do decimation of triangles to test
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
std::cout<<"Number of triangles= "<<_triangleSet.size()<<std::endl;
|
||||
std::cout<<"Number of points= "<<_pointSet.size()<<std::endl;
|
||||
std::cout<<"Number of edges= "<<_edgeSet.size()<<std::endl;
|
||||
std::cout<<"Number of boundary edges= "<<computeNumBoundaryEdges()<<std::endl;
|
||||
|
||||
// rebuild the _pointList from the _pointSet
|
||||
_originalPointList.clear();
|
||||
@@ -1047,7 +1160,7 @@ void Simplifier::simplify(osg::Geometry& geometry, float sampleRatio)
|
||||
|
||||
ec.setTargetNumOfTriangles((unsigned int)(sampleRatio*(float)ec.getNumOfTriangles()));
|
||||
|
||||
while (ec.collapseMinimumErrorEdge()) {}
|
||||
//while (ec.collapseMinimumErrorEdge()) {}
|
||||
|
||||
ec.copyBackToGeometry();
|
||||
|
||||
@@ -1062,7 +1175,7 @@ void Simplifier::simplify(osg::Geometry& geometry, unsigned int targetNumberOfTr
|
||||
|
||||
ec.setTargetNumOfTriangles(targetNumberOfTriangles);
|
||||
|
||||
while (ec.collapseMinimumErrorEdge()) {}
|
||||
//while (ec.collapseMinimumErrorEdge()) {}
|
||||
|
||||
ec.copyBackToGeometry();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user