From b38f491c1264f4bf05add6746c09a4ffa0a461f2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 28 Sep 2005 16:05:35 +0000 Subject: [PATCH] From Volker Walkiewicz (with tweaks from Robert Osfield): Fix to the update of the error metrics on the edges in the simplification mesh that are affected by an edge collapse. Addition of 'n' and 'p' keyboard control in osgsimplifier example to allow users to control the sample ratio manually. --- examples/osgsimplifier/osgsimplifier.cpp | 102 +++++++++++++++-------- include/osgUtil/Simplifier | 3 +- src/osgUtil/Simplifier.cpp | 46 ++++++++-- 3 files changed, 107 insertions(+), 44 deletions(-) diff --git a/examples/osgsimplifier/osgsimplifier.cpp b/examples/osgsimplifier/osgsimplifier.cpp index a724ca236..b7092db49 100644 --- a/examples/osgsimplifier/osgsimplifier.cpp +++ b/examples/osgsimplifier/osgsimplifier.cpp @@ -10,13 +10,53 @@ */ #include -#include #include #include -#include -#include #include + +class KeyboardEventHandler : public osgGA::GUIEventHandler +{ +public: + + KeyboardEventHandler(unsigned int& flag) : _flag(flag) + {} + + virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) + { + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()=='n') + { + _flag = 1; + return true; + } + if (ea.getKey()=='p') + { + _flag = 2; + return true; + } + break; + } + default: + break; + } + return false; + } + + virtual void accept(osgGA::GUIEventHandlerVisitor& v) + { + v.visit(*this); + } + +private: + + unsigned int& _flag; +}; + + int main( int argc, char **argv ) { @@ -50,8 +90,6 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->write(std::cout); return 1; } - std::string outputFileName; - while (arguments.read("-o",outputFileName)) {} // report any errors if they have occured when parsing the program aguments. if (arguments.errors()) @@ -85,39 +123,20 @@ int main( int argc, char **argv ) if (arguments.errors()) { arguments.writeErrorMessages(std::cout); - return 1; } - osg::Timer_t end_load_tick = osg::Timer::instance()->tick(); + osg::Timer_t end_tick = osg::Timer::instance()->tick(); - std::cout << "Time to load = "<delta_s(start_tick,end_load_tick)<1.0f) ratio=1.0f; + if (ratio root = (osg::Node*)loadedModel->clone(osg::CopyOp::DEEP_COPY_ALL); + root->accept(simplifier); + viewer.setSceneData(root.get()); + keyFlag = 0; + } } // wait for all cull and draw threads to complete before exit. diff --git a/include/osgUtil/Simplifier b/include/osgUtil/Simplifier index 0fcd04724..af2c33b3d 100644 --- a/include/osgUtil/Simplifier +++ b/include/osgUtil/Simplifier @@ -36,8 +36,7 @@ class OSGUTIL_EXPORT Simplifier : public osg::NodeVisitor void setMaximumError(float error) { _maximumError = error; } float getMaximumError() const { return _maximumError; } - - + class ContinueSimplificationCallback : public osg::Referenced { public: diff --git a/src/osgUtil/Simplifier.cpp b/src/osgUtil/Simplifier.cpp index a91a44cce..d00ac0ae4 100644 --- a/src/osgUtil/Simplifier.cpp +++ b/src/osgUtil/Simplifier.cpp @@ -24,7 +24,6 @@ using namespace osgUtil; - struct dereference_less { template @@ -417,7 +416,7 @@ public: osg::Vec3 new_normal = (p2->_vertex - p1->_vertex) ^ (p3->_vertex - p2->_vertex); new_normal.normalize(); - + float result = 1.0f - (new_normal.x() * _plane[0] + new_normal.y() * _plane[1] + new_normal.z() * _plane[2]); return result; } @@ -724,16 +723,17 @@ public: //if (edge->_triangles.size()<2) return false; //if (edge->_triangles.size()>2) return false; +#ifdef ORIGIANAL_CODE if (edge->getMaxNormalDeviationOnEdgeCollapse()>1.0) { -// osg::notify(osg::NOTICE)<<"collapseEdge("<getMaxNormalDeviationOnEdgeCollapse() = "<getMaxNormalDeviationOnEdgeCollapse()<getMaxNormalDeviationOnEdgeCollapse() = "<getMaxNormalDeviationOnEdgeCollapse()<getMaxNormalDeviationOnEdgeCollapse() = "<getMaxNormalDeviationOnEdgeCollapse()< > LocalEdgeList; @@ -868,19 +868,47 @@ public: } } + LocalEdgeList edges2UpdateErrorMetric; + LocalEdgeList::const_iterator newEdgeIt(newEdges.begin()); + while (newEdgeIt != newEdges.end()) + { + const Point* p = 0; + if (newEdgeIt->get()->_p1.get() != pNew) + p = newEdgeIt->get()->_p1.get(); + else + p = newEdgeIt->get()->_p2.get(); - // osg::notify(osg::NOTICE)<<"Edges to recalibarate "<_triangles.begin()); + while (triangleIt != p->_triangles.end()) + { + const Triangle* triangle = triangleIt->get(); + if (triangle->_e1->_p1 == p || triangle->_e1->_p2 == p) + edges2UpdateErrorMetric.insert(triangle->_e1); + if (triangle->_e2->_p1 == p || triangle->_e2->_p2 == p) + edges2UpdateErrorMetric.insert(triangle->_e2); + if (triangle->_e3->_p1 == p || triangle->_e3->_p2 == p) + edges2UpdateErrorMetric.insert(triangle->_e3); - for(LocalEdgeList::iterator itr=newEdges.begin(); - itr!=newEdges.end(); + ++triangleIt; + } + + ++newEdgeIt; + } + + edges2UpdateErrorMetric.insert(newEdges.begin(), newEdges.end()); + + // osg::notify(osg::NOTICE)<<"Edges to recalibarate "<get()<<")"<(itr->get())); } - return true; + return true; } unsigned int testEdge(Edge* edge)