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.
This commit is contained in:
@@ -10,13 +10,53 @@
|
||||
*/
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgUtil/Simplifier>
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
|
||||
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 = "<<osg::Timer::instance()->delta_s(start_tick,end_load_tick)<<std::endl;
|
||||
std::cout << "Time to load = "<<osg::Timer::instance()->delta_s(start_tick,end_tick)<<std::endl;
|
||||
|
||||
osgUtil::Simplifier simplifier(sampleRatio);
|
||||
loadedModel->accept(simplifier);
|
||||
simplifier.setSampleRatio(1.0f);
|
||||
simplifier.setMaximumError(0.4f);
|
||||
|
||||
//loadedModel->accept(simplifier);
|
||||
|
||||
osg::Timer_t end_simplifier_tick = osg::Timer::instance()->tick();
|
||||
|
||||
std::cout << "Time to simplify = "<<osg::Timer::instance()->delta_s(end_load_tick, end_simplifier_tick)<<std::endl;
|
||||
|
||||
osgUtil::TriStripVisitor tsv;
|
||||
tsv.setMinStripSize(3);
|
||||
loadedModel->accept(tsv);
|
||||
tsv.stripify();
|
||||
|
||||
osg::Timer_t end_tristrip_tick = osg::Timer::instance()->tick();
|
||||
|
||||
std::cout << "Time to tri strip = "<<osg::Timer::instance()->delta_s(end_simplifier_tick, end_tristrip_tick)<<std::endl;
|
||||
|
||||
// run optimization over the scene graph
|
||||
osgUtil::Optimizer optimzer;
|
||||
optimzer.optimize(loadedModel.get());
|
||||
|
||||
if (!outputFileName.empty())
|
||||
{
|
||||
std::cout << "Writing out scene graph as '" << outputFileName << "'"<<std::endl;
|
||||
osgDB::writeNodeFile(*loadedModel,outputFileName);
|
||||
return 0;
|
||||
}
|
||||
unsigned int keyFlag = 0;
|
||||
viewer.getEventHandlerList().push_front(new KeyboardEventHandler(keyFlag));
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(loadedModel.get());
|
||||
@@ -125,6 +144,10 @@ int main( int argc, char **argv )
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
float multiplier = 0.99f;
|
||||
float minRatio = 0.00f;
|
||||
float ratio = 0.5f;
|
||||
|
||||
while( !viewer.done() )
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
@@ -136,7 +159,20 @@ int main( int argc, char **argv )
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
|
||||
|
||||
if (keyFlag == 1 || keyFlag == 2)
|
||||
{
|
||||
if (keyFlag == 1) ratio *= multiplier;
|
||||
if (keyFlag == 2) ratio /= multiplier;
|
||||
if (ratio>1.0f) ratio=1.0f;
|
||||
if (ratio<minRatio) ratio=minRatio;
|
||||
|
||||
simplifier.setSampleRatio(ratio);
|
||||
osg::ref_ptr<osg::Node> 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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
using namespace osgUtil;
|
||||
|
||||
|
||||
struct dereference_less
|
||||
{
|
||||
template<class T, class U>
|
||||
@@ -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("<<edge<<") refused due to edge->getMaxNormalDeviationOnEdgeCollapse() = "<<edge->getMaxNormalDeviationOnEdgeCollapse()<<std::endl;
|
||||
return false;
|
||||
osg::notify(osg::NOTICE)<<"collapseEdge("<<edge<<") refused due to edge->getMaxNormalDeviationOnEdgeCollapse() = "<<edge->getMaxNormalDeviationOnEdgeCollapse()<<std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"collapseEdge("<<edge<<") edge->getMaxNormalDeviationOnEdgeCollapse() = "<<edge->getMaxNormalDeviationOnEdgeCollapse()<<std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef std::set< osg::ref_ptr<Edge> > 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 "<<newEdges.size()<<std::endl;
|
||||
TriangleSet::const_iterator triangleIt(p->_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 "<<edges2UpdateErrorMetric.size()<<std::endl;
|
||||
|
||||
for(LocalEdgeList::iterator itr=edges2UpdateErrorMetric.begin();
|
||||
itr!=edges2UpdateErrorMetric.end();
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"updateErrorMetricForEdge("<<itr->get()<<")"<<std::endl;
|
||||
updateErrorMetricForEdge(const_cast<Edge*>(itr->get()));
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int testEdge(Edge* edge)
|
||||
|
||||
Reference in New Issue
Block a user