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:
Robert Osfield
2005-09-28 16:05:35 +00:00
parent 3ef0406105
commit b38f491c12
3 changed files with 107 additions and 44 deletions

View File

@@ -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.

View File

@@ -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:

View File

@@ -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)