diff --git a/include/osgUtil/Simplifier b/include/osgUtil/Simplifier index 096932bb4..dde718d10 100644 --- a/include/osgUtil/Simplifier +++ b/include/osgUtil/Simplifier @@ -28,11 +28,47 @@ class OSGUTIL_EXPORT Simplifier : public osg::NodeVisitor { public: - Simplifier(float sampleRatio=0.5f); + Simplifier(float sampleRatio=1.0f, float maximumError=0.0f); + void setSampleRatio(float sampleRatio) { _sampleRatio = sampleRatio; } float getSampleRatio() const { return _sampleRatio; } + + void setMaximumError(float error) { _maximumError = error; } + float getMaximumError() const { return _maximumError; } + + class ContinueSimplificationCallback : public osg::Referenced + { + public: + /** return true if mesh should be continued to be simplified, return false to stop simplification.*/ + virtual bool continueSimplification(const Simplifier& simplifier, float nextError, unsigned int numOriginalPrimitives, unsigned int numRemainingPrimitives) const + { + return simplifier.continueSimplificationImplementation(nextError, numOriginalPrimitives, numRemainingPrimitives); + } + + protected: + virtual ~ContinueSimplificationCallback() {} + }; + + void setContinueSimplificationCallback(ContinueSimplificationCallback* cb) { _continueSimplificationCallback = cb; } + ContinueSimplificationCallback* getContinueSimplificationCallback() { return _continueSimplificationCallback.get(); } + const ContinueSimplificationCallback* getContinueSimplificationCallback() const { return _continueSimplificationCallback.get(); } + + + bool continueSimplification(float nextError, unsigned int numOriginalPrimitives, unsigned int numRemainingPrimitives) const + { + if (_continueSimplificationCallback.valid()) return _continueSimplificationCallback->continueSimplification(*this, nextError, numOriginalPrimitives, numRemainingPrimitives); + else return continueSimplificationImplementation(nextError, numOriginalPrimitives, numRemainingPrimitives); + } + + virtual bool continueSimplificationImplementation(float nextError, unsigned int numOriginalPrimitives, unsigned int numRemainingPrimitives) const + { + if (nextError<=getMaximumError()) return true; + return (float)numRemainingPrimitives > (float)numOriginalPrimitives * getSampleRatio(); + } + + virtual void apply(osg::Geode& geode) { for(unsigned int i=0;iasGeometry(); if (geometry) { - simplify(*geometry,_sampleRatio); + simplify(*geometry); } } } /** simply the geometry to defined ratio of original size.*/ - void simplify(osg::Geometry& geometry, float sampleRatio); - - void simplify(osg::Geometry& geometry, unsigned int targetNumberOfTriangles); + void simplify(osg::Geometry& geometry); protected: float _sampleRatio; + float _maximumError; + + osg::ref_ptr _continueSimplificationCallback; }; diff --git a/src/osgTerrain/DataSet.cpp b/src/osgTerrain/DataSet.cpp index ce4f3b578..565be76d9 100644 --- a/src/osgTerrain/DataSet.cpp +++ b/src/osgTerrain/DataSet.cpp @@ -2185,8 +2185,10 @@ osg::Node* DataSet::DestinationTile::createPolygonal() } #if 1 - osgUtil::Simplifier simplifier; - simplifier.simplify(*geometry,0.5f); // this will replace the normal vector with a new one + osgUtil::Simplifier simplifier(1.0f,geometry->getBound().radius()/2000.0f); +// osgUtil::Simplifier simplifier(1.0f,1.0f); + + simplifier.simplify(*geometry); // this will replace the normal vector with a new one #endif osg::Geode* geode = new osg::Geode; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index ae18bf74b..0065b7524 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -216,11 +215,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) node->accept(tsv); tsv.stripify(); } -#if 0 - // simplify geometry - osgUtil::Simplifier simplifier; - node->accept(simplifier); -#endif + } diff --git a/src/osgUtil/Simplifier.cpp b/src/osgUtil/Simplifier.cpp index 87007187f..992211479 100644 --- a/src/osgUtil/Simplifier.cpp +++ b/src/osgUtil/Simplifier.cpp @@ -43,15 +43,13 @@ public: struct Point; - EdgeCollapse(): - _targetNumTriangles(0) {} + EdgeCollapse() {} + ~EdgeCollapse() {} void setGeometry(osg::Geometry* geometry); osg::Geometry* getGeometry() { return _geometry; } - void setTargetNumOfTriangles(unsigned int num) { _targetNumTriangles = num; } - unsigned int getNumOfTriangles() { return _triangleSet.size(); } Point* computeInterpolatedPoint(Edge* edge,float r) const @@ -126,7 +124,11 @@ public: edge->_proposedPoint = computeOptimalPoint(edge); edge->updateMaxNormalDeviationOnEdgeCollapse(); - edge->setErrorMetric( computeErrorMetric( edge, edge->_proposedPoint.get())); + + if (edge->getMaxNormalDeviationOnEdgeCollapse()<=1.0f && !edge->isAdjacentToBoundary()) + edge->setErrorMetric( computeErrorMetric( edge, edge->_proposedPoint.get())); + else + edge->setErrorMetric( FLT_MAX ); _edgeSet.insert(keep_local_reference_to_edge); } @@ -145,9 +147,13 @@ public: { Edge* edge = itr->get(); - edge->_proposedPoint = computeOptimalPoint(edge); - edge->updateMaxNormalDeviationOnEdgeCollapse(); + edge->_proposedPoint = computeOptimalPoint(edge); + edge->updateMaxNormalDeviationOnEdgeCollapse(); + + if (edge->getMaxNormalDeviationOnEdgeCollapse()<=1.0f && !edge->isAdjacentToBoundary()) edge->setErrorMetric( computeErrorMetric( edge, edge->_proposedPoint.get())); + else + edge->setErrorMetric( FLT_MAX ); _edgeSet.insert(edge); } @@ -163,7 +169,7 @@ public: { Edge* edge = const_cast(itr->get()); - if (!edge->isAdjacentToBoundary()) + // if (!edge->isAdjacentToBoundary()) { osg::ref_ptr pNew = edge->_proposedPoint.valid()? edge->_proposedPoint : computeInterpolatedPoint(edge,0.5f); if (collapseEdge(edge,pNew.get())) return true; @@ -683,7 +689,7 @@ public: if (edge->getMaxNormalDeviationOnEdgeCollapse()>1.0) { - std::cout<<"collapseEdge("<getMaxNormalDeviationOnEdgeCollapse() = "<getMaxNormalDeviationOnEdgeCollapse()<getMaxNormalDeviationOnEdgeCollapse() = "<getMaxNormalDeviationOnEdgeCollapse()< > ArrayList; osg::Geometry* _geometry; ArrayList _arrayList; - unsigned int _targetNumTriangles; EdgeSet _edgeSet; TriangleSet _triangleSet; PointSet _pointSet; @@ -1341,41 +1346,6 @@ class CopyPointsToVertexArrayVisitor : public osg::ArrayVisitor void EdgeCollapse::copyBackToGeometry() { -#if 1 - updateErrorMetricForAllEdges(); -#endif - std::cout<<"******* BEFORE EDGE COLLAPSE ********"<<_triangleSet.size()<getErrorMetric() , numOriginalPrimitives, ec._triangleSet.size()) && + ec.collapseMinimumErrorEdge()) + { + std::cout<<"Collapsed edge ec._triangleSet.size()="<