//============================================================================= // // OpenMesh // Copyright (C) 2003 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 Lesser General Public License as published // by the Free Software Foundation, version 2.1. // // 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // //----------------------------------------------------------------------------- // // $Revision: 1800 $ // $Date: 2008-05-19 11:51:23 +0200 (Mo, 19. Mai 2008) $ // //============================================================================= //============================================================================= // // Class SoOpenMeshNodeT - implementation // //============================================================================= #define OPENMESH_SOOPENMESHNODE_CC //== INCLUDES ================================================================= #include #include #include #include #include #include #include #include "SoOpenMeshNodeT.hh" // Attention must be included after SoOpenMeshNodeT.hh // as it redefines several macros! #include "SoOpenMeshSupport.hh" #include //== NAMESPACES ============================================================== namespace OpenMesh { //== IMPLEMENTATION ========================================================== // Helper functions: draw vertices inline void glVertex(const OpenMesh::Vec3f& _v) { glVertex3fv(_v); } inline void glVertex(const OpenMesh::Vec3d& _v) { glVertex3dv(_v); } // Helper functions: draw normal inline void glNormal(const OpenMesh::Vec3f& _n) { glNormal3fv(_n); } inline void glNormal(const OpenMesh::Vec3d& _n) { glNormal3dv(_n); } // Helper function: convert Vec to SbVec3f template inline SbVec3f sbvec3f(const Vec& _v) { return SbVec3f(_v[0], _v[1], _v[2]); } //----------------------------------------------------------------------------- template void SoOpenMeshNodeT::initClass() { SO_NODE_INIT_CLASS(SoOpenMeshNodeT, SoShape, "Shape"); } //----------------------------------------------------------------------------- template SoOpenMeshNodeT::SoOpenMeshNodeT(const Mesh* _mesh) : mesh_(_mesh) { SO_NODE_CONSTRUCTOR(SoOpenMeshNodeT); } //----------------------------------------------------------------------------- template void SoOpenMeshNodeT::GLRender(SoGLRenderAction *action) { if (mesh_ && shouldGLRender(action)) { SoState* state = action->getState(); SbBool send_normals = (SoLightModelElement::get(state) != SoLightModelElement::BASE_COLOR); SoMaterialBundle mb(action); mb.sendFirst(); drawFaces(send_normals); } } //---------------------------------------------------------------------------- template void SoOpenMeshNodeT:: drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type) { typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()), f_end(mesh_->faces_end()); typename Mesh::ConstFaceVertexIter fv_it; if (_send_normals) { glBegin(GL_TRIANGLES); for (; f_it!=f_end; ++f_it) { glNormal(mesh_->normal(f_it)); fv_it = mesh_->cfv_iter(f_it.handle()); glVertex(mesh_->point(fv_it)); ++fv_it; glVertex(mesh_->point(fv_it)); ++fv_it; glVertex(mesh_->point(fv_it)); } glEnd(); } else { glBegin(GL_TRIANGLES); for (; f_it!=f_end; ++f_it) { fv_it = mesh_->cfv_iter(f_it.handle()); glVertex(mesh_->point(fv_it)); ++fv_it; glVertex(mesh_->point(fv_it)); ++fv_it; glVertex(mesh_->point(fv_it)); } glEnd(); } } //---------------------------------------------------------------------------- template void SoOpenMeshNodeT:: drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type) { typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()), f_end(mesh_->faces_end()); typename Mesh::ConstFaceVertexIter fv_it; if (_send_normals) { for (; f_it!=f_end; ++f_it) { glBegin(GL_POLYGON); glNormal(mesh_->normal(f_it)); for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it) glVertex(mesh_->point(fv_it)); glEnd(); } } else { for (; f_it!=f_end; ++f_it) { glBegin(GL_POLYGON); for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it) glVertex(mesh_->point(fv_it)); glEnd(); } } } //----------------------------------------------------------------------------- template void SoOpenMeshNodeT::generatePrimitives(SoAction* _action) { if (mesh_) genPrimitives(_action); } //---------------------------------------------------------------------------- template void SoOpenMeshNodeT:: genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type) { typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()), f_end(mesh_->faces_end()); typename Mesh::ConstFaceVertexIter fv_it; SoPrimitiveVertex pv; beginShape(_action, TRIANGLES); for (; f_it!=f_end; ++f_it) { pv.setNormal(sbvec3f(mesh_->normal(f_it))); fv_it = mesh_->cfv_iter(f_it.handle()); pv.setPoint(sbvec3f(mesh_->point(fv_it))); shapeVertex(&pv); ++fv_it; pv.setPoint(sbvec3f(mesh_->point(fv_it))); shapeVertex(&pv); ++fv_it; pv.setPoint(sbvec3f(mesh_->point(fv_it))); shapeVertex(&pv); } endShape(); } //---------------------------------------------------------------------------- template void SoOpenMeshNodeT:: genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type) { typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()), f_end(mesh_->faces_end()); typename Mesh::ConstFaceVertexIter fv_it; SoPrimitiveVertex pv; for (; f_it!=f_end; ++f_it) { beginShape(_action, POLYGON); pv.setNormal(sbvec3f(mesh_->normal(f_it))); for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it) { pv.setPoint(sbvec3f(mesh_->point(fv_it))); shapeVertex(&pv); } endShape(); } } //----------------------------------------------------------------------------- template void SoOpenMeshNodeT::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er) { if (mesh_ && mesh_->n_vertices()) { typename Mesh::ConstVertexIter vIt(mesh_->vertices_begin()); typename Mesh::ConstVertexIter vEnd(mesh_->vertices_end()); typename Mesh::Point min(mesh_->point(vIt)); typename Mesh::Point max(mesh_->point(vIt)); for (++vIt; vIt != vEnd; ++vIt) { max.maximize(mesh_->point(vIt)); min.minimize(mesh_->point(vIt)); } box.setBounds(SbVec3f(min[0],min[1],min[2]), SbVec3f(max[0],max[1],max[2])); } else box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0)); } //----------------------------------------------------------------------------- #if 0 /* As we are using templates, we cannot use the predefined macro SO_NODE_SOURCE to automatically generate the following piece of code. Ugly, but necessary. */ template SoType SoOpenMeshNodeT::classTypeId; template SoFieldData *SoOpenMeshNodeT::fieldData; template const SoFieldData **SoOpenMeshNodeT::parentFieldData; template SbBool SoOpenMeshNodeT::firstInstance = TRUE; template SoType SoOpenMeshNodeT::getTypeId() const { return classTypeId; } template const SoFieldData* SoOpenMeshNodeT::getFieldData() const { SO__NODE_CHECK_CONSTRUCT("SoOpenMeshNodeT"); return fieldData; } template void* SoOpenMeshNodeT::createInstance() { return (void *)(new SoOpenMeshNodeT); } #else SO_NODE_SOURCE(SoOpenMeshNodeT); #endif //============================================================================= } // namespace OpenMesh //=============================================================================