📄 osgviewer.cc
字号:
//=============================================================================// // OpenMesh // Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen // www.openmesh.org // //-----------------------------------------------------------------------------// // License // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Library General Public License as published // by the Free Software Foundation, version 2. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // //=============================================================================#include <memory>#include <iostream>#include <iomanip>#include <stdexcept>#define OSG_WITH_GLUT#include <GL/glut.h>#include <OpenSG/OSGConfig.h>#include <OpenSG/OSGGLUTWindow.h>#include <OpenSG/OSGSimpleSceneManager.h>#include <OpenSG/OSGSceneFileHandler.h>#include <OpenSG/OSGTriangleIterator.h>#include <OpenSG/OSGFaceIterator.h>#include <OpenMesh/Core/IO/MeshIO.hh> // always before kernel type#include <OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh>#include <OpenMesh/Tools/Kernel_OSG/bindT.hh>#include <OpenMesh/Tools/Utils/Timer.hh>#include <OpenMesh/Tools/Subdivider/Uniform/LoopT.hh>#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>//-----------------------------------------------------------------------------using namespace OSG;//-----------------------------------------------------------------------------struct MyTraits : public OpenMesh::Kernel_OSG::Traits{ HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge ); VertexAttributes ( OpenMesh::Attributes::Normal ); FaceAttributes ( OpenMesh::Attributes::Normal );};typedef OpenMesh::Kernel_OSG::TriMesh_OSGArrayKernelT<MyTraits> MyMesh;typedef OpenMesh::Subdivider::Uniform::LoopT<MyMesh> Loop;typedef OpenMesh::Smoother::JacobiLaplaceSmootherT<MyMesh> Smoother;//-----------------------------------------------------------------------------class MeshContainer{public: typedef std::vector<MyMesh*> meshbag_t; const size_t InvalidIndex;public: MeshContainer() : InvalidIndex(size_t(-1)) {} ~MeshContainer() { std::vector<MyMesh*>::iterator it = meshes_.begin(); for(;it != meshes_.end(); ++it) delete *it; } size_t size() const { return meshes_.size(); } MyMesh& operator[]( size_t idx ) { return *(meshes_[idx]); } const MyMesh& operator [] ( size_t idx ) const { return *(meshes_[idx]); } bool bind( osg::GeometryPtr geo ) { std::auto_ptr<MyMesh> obj(new MyMesh); return (OpenMesh::Kernel_OSG::bind< MyMesh >( *obj, geo)) ? (meshes_.push_back(obj.release()), true) : false; }private: std::vector<MyMesh*> meshes_;};//-----------------------------------------------------------------------------struct Globals{ // OpenSG specific entities SimpleSceneManager* mgr; GLUTWindowPtr gwin; NodePtr root; std::vector<GeometryPtr> geos; size_t sel; bool statistics; // OpenMesh specific entities MeshContainer meshes;} g;//-----------------------------------------------------------------------------void display(void);void reshape(int width, int height);void mouse(int button, int state, int x, int y);void keyboard(unsigned char key, int x, int y);void motion(int x, int y);int setupGLUT(int *argc, char *argv[]);//-----------------------------------------------------------------------------int setupGLUT(int *argc, char *argv[]){ glutInit(argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); int winid = glutCreateWindow("OpenMesh within OpenSG"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc(keyboard); return winid;}//-----------------------------------------------------------------------------/* This function uses the fact that ::dcast() acts like dynamic_cast. It tries to dcast the core to a GeometryPtr, and tests the result to see if it actually was derived from Geometry.*/Action::ResultE bindGeo(NodePtr& node){ GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if (geo!=NullFC) { if ( g.meshes.bind( geo ) ) { std::cout << " Geometry connected to OpenMesh object\n"; g.geos.push_back(geo); g.sel = g.meshes.size()-1; assert( g.geos.size() == g.meshes.size() ); } else std::cerr << " Warning! Could not bind the OpenMesh" << " object to the geometry!\n"; } return Action::Continue; }//-----------------------------------------------------------------------------int main(int argc, char **argv){ // OSG init osgInit(argc,argv); int winid = setupGLUT(&argc, argv); g.gwin = GLUTWindow::create(); g.gwin->setId(winid); g.gwin->init(); // create root node with core std::cout << "Create root node with core\n"; g.root = Node::create(); NodeCorePtr core = Group::create(); osg::beginEditCP(g.root); { g.root->setCore(core); } osg::endEditCP(g.root); // load the scene std::cout << "Load a scene from '" << argv[1] << "'\n"; NodePtr node = SceneFileHandler::the().read( argv[1] ); if ( node != NullFC ) { osg::beginEditCP(g.root); { g.root->addChild(node); } osg::endEditCP(g.root); } else return 1; // bind all geometry nodes to an OpenMesh std::cout << "Bind all geometry nodes\n"; traverse(g.root, osgTypedFunctionFunctor1CPtrRef<Action::ResultE,NodePtr>(bindGeo)); if (!g.meshes.size()) { std::cerr << " No geometry found. Nothing to do!\n"; return 1; } else { std::cout << " Number of bound geometry: " << g.meshes.size() << std::endl; g.meshes[0].update_face_normals(); g.meshes[0].update_vertex_normals(); } // create the SimpleSceneManager helper std::cout << "Create simple scene manager\n"; g.mgr = new SimpleSceneManager; // tell the manager what to manage g.mgr->setWindow(g.gwin); g.mgr->setRoot (g.root); // g.mgr->useOpenSGLogo(); g.mgr->setStatistics(false); // show the whole scene std::cout << "Display everything\n"; g.mgr->showAll(); glutMainLoop(); return 0;}// --------------------------------------------------------------- display ----void display(void){ g.mgr->redraw();}// --------------------------------------------------------------- reshape ----void reshape(int w, int h){ g.mgr->resize(w, h); glutPostRedisplay();}// ----------------------------------------------------------------- mouse ----void mouse(int button, int state, int x, int y){ if (state) g.mgr->mouseButtonRelease(button, x, y); else g.mgr->mouseButtonPress(button, x, y); glutPostRedisplay();}//----------------------------------------------------------------- motion ----void motion(int x, int y){ g.mgr->mouseMove(x, y); glutPostRedisplay();}// -------------------------------------------------------------- keyboard ----void keyboard(unsigned char key, int x, int y){#define MESH g.meshes[g.sel]#define GEO g.geos[g.sel] OpenMesh::Utils::Timer t; using namespace std; switch(key) { case 27: // escape exit(0); break; case 'i': cout << "OpenMesh information for obj #" << g.sel << ":\n"; cout << " #Vertices: " << MESH.n_vertices() << endl; cout << " #Faces: " << MESH.n_faces() << endl; cout << " #Edges: " << MESH.n_edges() << endl; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((size_t(key)-size_t('0')) < g.meshes.size()) { g.sel = (size_t(key)-size_t('0')); cout << "Selected geometry #" << g.sel << endl; } break; case '+': g.sel = ++g.sel % g.meshes.size(); cout << "Selected geometry #" << g.sel << endl; break; case '-': g.sel = (g.sel + g.meshes.size()-1) % g.meshes.size(); cout << "Selected geometry #" << g.sel << endl; break; case 's': { cout << "Smoothing selected geometry..."; t.start(); Smoother smoother( g.meshes[g.sel] ); smoother.initialize( Smoother::Normal, Smoother::C0 ); beginEditCP(g.geos[g.sel]); smoother.smooth(2); endEditCP(g.geos[g.sel]); t.stop(); cout << "done. " << t.as_string() << endl; glutPostRedisplay(); break; } case 'u': { cout << "Loop subdivision..."; t.start(); Loop loop; beginEditCP( GEO ); loop( MESH, 1 ); MESH.update_normals(); endEditCP( GEO ); t.stop(); cout << "done. " << t.as_string() << endl; glutPostRedisplay(); break; } }#undef GEO#undef MESH}//=============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -