OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
WTriangleMesh.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WTRIANGLEMESH_H
00026 #define WTRIANGLEMESH_H
00027 
00028 #include <list>
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <osg/Geode>
00033 
00034 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00035 #include "../common/WAssert.h"
00036 #include "../common/WColor.h"
00037 #include "../common/WTransferable.h"
00038 #include "WExportWGE.h"
00039 
00040 /**
00041  * Triangle mesh data structure allowing for convenient access of the elements.
00042  */
00043 class WGE_EXPORT WTriangleMesh  : public WTransferable
00044 {
00045 friend class WTriangleMeshTest;
00046 public:
00047 
00048     /**
00049      * Shared pointer
00050      */
00051     typedef boost::shared_ptr< WTriangleMesh > SPtr;
00052 
00053     /**
00054      * Const shared pointer
00055      */
00056     typedef boost::shared_ptr< const WTriangleMesh > ConstSPtr;
00057 
00058     /**
00059      * constructor that already reserves space for a given number of triangles and vertexes
00060      *
00061      * \param vertNum
00062      * \param triangleNum
00063      */
00064     WTriangleMesh( size_t vertNum, size_t triangleNum );
00065 
00066     /**
00067      * Constructs a new mesh out of the given vertices and triangles.
00068      *
00069      * \param vertices Vec3Array storing all vertices
00070      * \param triangles Vector of consecutive vertex indices where each 3 IDs are a triangle starting at 0,1,2 for first triangle 3,4,5 for the second
00071      */
00072     WTriangleMesh( osg::ref_ptr< osg::Vec3Array > vertices, const std::vector< size_t >& triangles );
00073 
00074     /**
00075      * destructor
00076      */
00077     virtual ~WTriangleMesh();
00078 
00079     /**
00080      * Returns a prototype instantiated with the true type of the deriving class.
00081      *
00082      * \return the prototype.
00083      */
00084     static boost::shared_ptr< WPrototyped > getPrototype();
00085 
00086     /**
00087      * Gets the name of this prototype.
00088      *
00089      * \return the name.
00090      */
00091     virtual const std::string getName() const;
00092 
00093     /**
00094      * Gets the description for this prototype.
00095      *
00096      * \return the description
00097      */
00098     virtual const std::string getDescription() const;
00099 
00100     /**
00101      * adds a vertex position to the mesh
00102      *
00103      * \param vert
00104      */
00105     void addVertex( osg::Vec3 vert );
00106 
00107     /**
00108      * adds a vertex position to the mesh
00109      *
00110      * \param x
00111      * \param y
00112      * \param z
00113      */
00114     void addVertex( float x, float y, float z );
00115 
00116     /**
00117      * adds a vertex position to the mesh
00118      *
00119      * \param vert
00120      */
00121     void addVertex( WPosition vert );
00122 
00123     /**
00124      * Adds a texture coordinate for the vertex.
00125      *
00126      * \param texCoord the texture coordinate
00127      */
00128     void addTextureCoordinate( osg::Vec3 texCoord );
00129 
00130     /**
00131      * Adds a texture coordinate for the vertex.
00132      *
00133      * \param x texture coordinate X
00134      * \param y texture coordinate Y
00135      * \param z texture coordinate Z
00136      */
00137     void addTextureCoordinate( float x, float y, float z );
00138 
00139     /**
00140      * adds a tringle to the mesh
00141      *
00142      * \param vert0 index of the first vertex
00143      * \param vert1 index of the second vertex
00144      * \param vert2 index of the third vertex
00145      */
00146     void addTriangle( size_t vert0, size_t vert1, size_t vert2 );
00147 
00148     /**
00149      * adds a tringle and its 3 vertexes  to the mesh
00150      *
00151      * \param vert0 position of the first vertex
00152      * \param vert1 position of the second vertex
00153      * \param vert2 position of the third vertex
00154      */
00155     void addTriangle( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
00156 
00157     /**
00158      * sets a vertex to a new position
00159      *
00160      * \param index
00161      * \param vert
00162      */
00163     void setVertex( size_t index, osg::Vec3 vert );
00164 
00165     /**
00166      * sets the normal for a given vertex
00167      *
00168      * \param index
00169      * \param normal
00170      */
00171     void setVertexNormal( size_t index, osg::Vec3 normal );
00172 
00173     /**
00174      * sets the normal for a given vertex
00175      *
00176      * \param index
00177      * \param normal
00178      */
00179     void setVertexNormal( size_t index, WPosition normal );
00180 
00181     /**
00182      * sets the color for a given vertex
00183      *
00184      * \param index
00185      * \param color
00186      */
00187     void setVertexColor( size_t index, osg::Vec4 color );
00188 
00189     /**
00190      * sets the color for a given triangle
00191      *
00192      * \param index
00193      * \param color
00194      */
00195     void setTriangleColor( size_t index, osg::Vec4 color );
00196 
00197     /**
00198      * Return triangle colors
00199      *
00200      * \return OSG Vec4 Array of triangle colors
00201      */
00202     osg::ref_ptr< osg::Vec4Array > getTriangleColors() const;
00203 
00204     /**
00205      * getter
00206      *
00207      * \return pointer to the vertex array
00208      */
00209     osg::ref_ptr< osg::Vec3Array > getVertexArray();
00210 
00211     /**
00212      * Returns a const reference pointer to the vertex array.
00213      *
00214      * \return vertex array
00215      */
00216     osg::ref_ptr< const osg::Vec3Array > getVertexArray() const;
00217 
00218     /**
00219      * Returns a reference pointer to the texture coordinate array.
00220      *
00221      * \return texture coordinate array
00222      */
00223     osg::ref_ptr< osg::Vec3Array > getTextureCoordinateArray();
00224 
00225     /**
00226      * Returns a const reference pointer to the texture coordinate array.
00227      *
00228      * \return texture coordinate array
00229      */
00230     osg::ref_ptr< const osg::Vec3Array > getTextureCoordinateArray() const;
00231 
00232     /**
00233      * getter
00234      *
00235      * \param forceRecalc
00236      * \return pointer to the vertex normal array
00237      */
00238     osg::ref_ptr< osg::Vec3Array > getVertexNormalArray( bool forceRecalc = false );
00239 
00240     /**
00241      * getter
00242      *
00243      * \return pointer to the vertex color array
00244      */
00245     osg::ref_ptr< osg::Vec4Array > getVertexColorArray();
00246 
00247     /**
00248      * Returns a const reference to the vertex ids of the triangles.
00249      *
00250      * \return The triangle vertex id list
00251      */
00252     const std::vector< size_t >& getTriangles() const;
00253 
00254     /**
00255      * getter
00256      *
00257      * \param forceRecalc
00258      * \return pointer to the triangle normal array
00259      */
00260     osg::ref_ptr< osg::Vec3Array > getTriangleNormalArray( bool forceRecalc = false );
00261 
00262 
00263     /**
00264      * getter
00265      *
00266      * \param index
00267      * \return vertex
00268      */
00269     osg::Vec3 getVertex( size_t index ) const;
00270 
00271     /**
00272      * getter
00273      *
00274      * \param index
00275      * \return color
00276      */
00277     osg::Vec4 getVertColor( size_t index ) const;
00278 
00279     /**
00280      * getter
00281      *
00282      * \param triId
00283      * \param vertNum
00284      * \return vertex
00285      */
00286     osg::Vec3 getTriVert( size_t triId, size_t vertNum );
00287 
00288     /**
00289      * getter
00290      *
00291      * \param index
00292      * \return normal
00293      */
00294     WVector3d getNormal( size_t index ) const;
00295 
00296     /**
00297      * getter
00298      *
00299      * \return number of vertices in the mesh
00300      */
00301     size_t vertSize() const;
00302 
00303     /**
00304      * getter
00305      *
00306      * \return number of triangles in the mesh
00307      */
00308     size_t triangleSize() const;
00309 
00310     /**
00311      * performs a loop subdivision on the triangle mesh
00312      */
00313     void doLoopSubD();
00314 
00315     /**
00316      * returns the id of the first vertex of a triangle
00317      *
00318      * \param triId id of the triangle
00319      * \return id of the vertex
00320      */
00321     size_t getTriVertId0( size_t triId ) const;
00322 
00323     /**
00324      * returns the id of the second vertex of a triangle
00325      *
00326      * \param triId id of the triangle
00327      * \return id of the vertex
00328      */
00329     size_t getTriVertId1( size_t triId ) const;
00330 
00331     /**
00332      * return the id of the third vertex of a triangle
00333      *
00334      * \param triId id of the triangle
00335      * \return id of the vertex
00336      */
00337     size_t getTriVertId2( size_t triId ) const;
00338 
00339     /**
00340      *  adds a mesh to the existing, no check for duplicate vertexes is performed, an additional
00341      *  vector may be specified to move the mesh to add
00342      *
00343      *  \param mesh
00344      *  \param xOff
00345      *  \param yOff
00346      *  \param zOff
00347      */
00348     void addMesh( boost::shared_ptr<WTriangleMesh> mesh, float xOff = 0., float yOff = 0., float zOff = 0. );
00349 
00350     /**
00351      *  moves the entire mesh to a new postion
00352      *
00353      *  \param xOff
00354      *  \param yOff
00355      *  \param zOff
00356      */
00357     void translateMesh( float xOff, float yOff, float zOff );
00358 
00359     /**
00360      * multiplies the vertex vectors of the mesh with a given number
00361      *
00362      * \param zoom
00363      */
00364     void zoomMesh( float zoom );
00365 
00366     /**
00367      * Checks if two meshes are exactly the same. Same number of triangles, and
00368      * points, and indices as well as same ordering. Keep in mind different
00369      * ordering might result in the same structure but is considered different
00370      * here.
00371      *
00372      * \param rhs The other mesh to compare with
00373      *
00374      * \return True if and only if both: vertices and triangles are exactly the same.
00375      */
00376     bool operator==( const WTriangleMesh& rhs ) const;
00377 
00378 protected:
00379     static boost::shared_ptr< WPrototyped > m_prototype; //!< The prototype as singleton.
00380 private:
00381     /**
00382      * we don't allow the standard constructor
00383      */
00384     WTriangleMesh();
00385 
00386     /**
00387      * removes a vertex from the vertex array, if any triangles still index that vertex they will be
00388      * removed if forceRemoveTriangle is true
00389      *
00390      * \param index the index of the vertex to remove
00391      */
00392     void removeVertex( size_t index );
00393 
00394     /**
00395      * removes a triangle from the mesh
00396      *
00397      * \param index the triangle to remove
00398      */
00399     void removeTriangle( size_t index );
00400 
00401     /**
00402      * recalculates the vertex normals
00403      */
00404     void recalcVertNormals();
00405 
00406     /**
00407      * calculates a normal from the 3 points in space defining a triangle
00408      *
00409      * \param triangle
00410      *
00411      * \return the normal of the triangle
00412      */
00413     osg::Vec3 calcTriangleNormal( size_t triangle );
00414 
00415     /**
00416      * calculates a normal from the 3 points in space
00417      *
00418      * \param vert0 vertex 1
00419      * \param vert1 vertex 2
00420      * \param vert2 vertex 3
00421      *
00422      * \return the normal of the plane defined by these three points
00423      */
00424     osg::Vec3 calcNormal( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
00425 
00426     /**
00427      * updates the list for which vertexes appear in which triangle
00428      */
00429     void updateVertsInTriangles();
00430 
00431     /**
00432      * calculates neighbor information for triangles
00433      */
00434     void calcNeighbors();
00435 
00436     /**
00437      * returns the triangle index of a triangle neighboring a given edge of a vertex
00438      *
00439      * \param coVert1
00440      * \param coVert2
00441      * \param triangleNum
00442      *
00443      * \return the number of the neighboring triangle.
00444      */
00445     size_t getNeighbor( const size_t coVert1, const size_t coVert2, const size_t triangleNum );
00446 
00447     /**
00448      * higher level access function to the triangle vector, sets the first vertex of a triangle to
00449      * a given vertex id
00450      *
00451      * \param triId the id of the triangle to modify
00452      * \param vertId new id of the first vertex
00453      */
00454     void setTriVert0( size_t triId, size_t vertId );
00455 
00456     /**
00457      * higher level access function to the triangle vector, sets the second vertex of a triangle to
00458      * a given vertex id
00459      *
00460      * \param triId the id of the triangle to modify
00461      * \param vertId new id of the second vertex
00462      */
00463     void setTriVert1( size_t triId, size_t vertId );
00464 
00465     /**
00466      * higher level access function to the triangle vector, sets the third vertex of a triangle to
00467      * a given vertex id
00468      *
00469      * \param triId the id of the triangle to modify
00470      * \param vertId new id of the third vertex
00471      */
00472     void setTriVert2( size_t triId, size_t vertId );
00473 
00474 
00475     // the next functions are helper functions for the loop subdivision algorithm and exist only for that
00476     // purpose, for more information read http://research.microsoft.com/en-us/um/people/cloop/thesis.pdf
00477 
00478 
00479     /**
00480      * changes the vertex ids of a triangle
00481      *
00482      * \param triId
00483      * \param vertId1
00484      * \param vertId2
00485      * \param vertId3
00486      */
00487     void loopSetTriangle( size_t triId, size_t vertId1, size_t vertId2, size_t vertId3 );
00488 
00489     /**
00490      * erases a triangle from the vertexe's list of triangles it is part of
00491      *
00492      * \param triId
00493      * \param vertId
00494      */
00495     void loopEraseTriangleFromVertex( size_t triId, size_t vertId );
00496 
00497     /**
00498      * calculates the new position of a vertex depending on it's location in the grid and number of neighbors
00499      *
00500      * \param vertId the vertex id
00501      * \return new position in 3D space
00502      */
00503     osg::Vec3 loopCalcNewPosition( size_t vertId );
00504 
00505     /**
00506      * inserts the center triangle in a given triangle,
00507      *
00508      * \param triId the triangle id
00509      */
00510     void loopInsertCenterTriangle( size_t triId );
00511 
00512     /**
00513      * inserts the 3 corner triangles in a given triangle
00514      *
00515      * \param triId the triangle id
00516      */
00517     void loopInsertCornerTriangles( size_t triId );
00518 
00519     /**
00520      * calculates the vertex id for a given edge, inserts a new vertex of none exists yet
00521      *
00522      * \param triId the triangle id
00523      * \param edgeV1
00524      * \param edgeV2
00525      * \param V3
00526      * \return index of the vertex
00527      */
00528     size_t loopCalcEdgeVert( size_t triId, size_t edgeV1, size_t edgeV2, size_t V3 );
00529 
00530     /**
00531      * loop helper function
00532      * \param n
00533      * \return alpha
00534      */
00535     double loopGetAlpha( int n );
00536 
00537     /**
00538      * returns the id of the next vertex int he triangle
00539      *
00540      * \param triNum id of the triangle
00541      * \param vertNum id of the vertex
00542      * \return id of the next vertex
00543      */
00544     size_t loopGetNextVertex( size_t triNum, size_t vertNum );
00545 
00546     /**
00547      * returns the id of the third vertex of a triangle for two given vertexes
00548      *
00549      * \param coVert1
00550      * \param coVert2
00551      * \param triangleNum
00552      * \return id of the third vertex
00553      */
00554     size_t loopGetThirdVert( size_t coVert1, size_t coVert2, size_t triangleNum );
00555 
00556 
00557     size_t m_countVerts; //!< number of vertexes in the mesh
00558 
00559     size_t m_countTriangles; //!< number of triangles in the mesh
00560 
00561     bool m_meshDirty; //!< flag indicating a change took place which requires a recalculation of components
00562 
00563     bool m_neighborsCalculated; //!< flag indicating whether the neighbor information has been calculated yet
00564 
00565     osg::ref_ptr< osg::Vec3Array > m_verts; //!< array containing the vertices
00566 
00567     osg::ref_ptr< osg::Vec3Array > m_textureCoordinates; //!< array containing the texture coordinates
00568 
00569     osg::ref_ptr< osg::Vec3Array > m_vertNormals; //!< array containing the vertex normals
00570 
00571     osg::ref_ptr< osg::Vec4Array > m_vertColors; //!< array containing vertex colors
00572 
00573     std::vector< size_t > m_triangles; //!< array containing the triangles
00574 
00575     osg::ref_ptr< osg::Vec3Array > m_triangleNormals; //!< array containing the triangle normals
00576 
00577     osg::ref_ptr< osg::Vec4Array > m_triangleColors; //!< array containing the triangle colors
00578 
00579     // helper structures
00580     std::vector < std::vector< size_t > > m_vertexIsInTriangle; //!< for each vertex, list of triangles it is part of
00581 
00582     std::vector< std::vector< size_t > > m_triangleNeighbors; //!< edge neighbors for each triangle
00583 
00584     size_t m_numTriVerts; //!< stores the number of vertexes before the loop subdivion is run, needed by the loop algorithm
00585 
00586     size_t m_numTriFaces; //!< stores the number of triangles before the loop subdivion is run, needed by the loop algorithm
00587 };
00588 
00589 /**
00590  * TriangleMesh utils
00591  */
00592 namespace tm_utils
00593 {
00594     /**
00595      * Decompose the given mesh into connected components.
00596      *
00597      * \param mesh The triangle mesh to decompose
00598      *
00599      * \return List of components where each of them is a WTriangleMesh again.
00600      */
00601     WGE_EXPORT boost::shared_ptr< std::list< boost::shared_ptr< WTriangleMesh > > > componentDecomposition( const WTriangleMesh& mesh );
00602 
00603     /**
00604      * Prints for each mesh \#vertices and \#triangles, as well as each triangle with its positions. No point IDs are printed.
00605      *
00606      * \param os Output stream to print on.
00607      * \param rhs The mesh instance.
00608      *
00609      * \return The output stream again for further usage.
00610      */
00611     WGE_EXPORT std::ostream& operator<<( std::ostream& os, const WTriangleMesh& rhs );
00612 }
00613 
00614 inline bool WTriangleMesh::operator==( const WTriangleMesh& rhs ) const
00615 {
00616     return std::equal( m_verts->begin(), m_verts->end(), rhs.m_verts->begin() ) &&
00617            std::equal( m_triangles.begin(), m_triangles.end(), rhs.m_triangles.begin() );
00618 }
00619 
00620 inline void WTriangleMesh::addTextureCoordinate( osg::Vec3 texCoord )
00621 {
00622     ( *m_textureCoordinates )[m_countVerts-1] = texCoord;
00623 }
00624 
00625 inline void WTriangleMesh::addTextureCoordinate( float x, float y, float z )
00626 {
00627     addTextureCoordinate( osg::Vec3( x, y, z ) );
00628 }
00629 
00630 inline void WTriangleMesh::addVertex( osg::Vec3 vert )
00631 {
00632     if( ( *m_verts ).size() == m_countVerts )
00633     {
00634         ( *m_verts ).resize( m_countVerts + 1 );
00635     }
00636     if( ( *m_textureCoordinates ).size() == m_countVerts )
00637     {
00638         ( *m_textureCoordinates ).resize( m_countVerts + 1 );
00639     }
00640 
00641     ( *m_verts )[m_countVerts] = vert;
00642     ++m_countVerts;
00643 }
00644 
00645 inline const std::string WTriangleMesh::getName() const
00646 {
00647     return "WTriangleMesh";
00648 }
00649 
00650 inline const std::string WTriangleMesh::getDescription() const
00651 {
00652     return "Triangle mesh data structure allowing for convenient access of the elements.";
00653 }
00654 
00655 inline void WTriangleMesh::setTriVert0( size_t triId, size_t vertId )
00656 {
00657     WAssert( triId < m_countTriangles, "set tri vert 0: triangle id out of range" );
00658     WAssert( vertId < m_countVerts, "vertex id out of range" );
00659     m_triangles[ triId * 3 ] = vertId;
00660 }
00661 
00662 inline void WTriangleMesh::setTriVert1( size_t triId, size_t vertId )
00663 {
00664     WAssert( triId < m_countTriangles, "set tri vert 1: triangle id out of range" );
00665     WAssert( vertId < m_countVerts, "vertex id out of range" );
00666     m_triangles[ triId * 3 + 1] = vertId;
00667 }
00668 
00669 inline void WTriangleMesh::setTriVert2( size_t triId, size_t vertId )
00670 {
00671     WAssert( triId < m_countTriangles, "set tri vert 2: triangle id out of range" );
00672     WAssert( vertId < m_countVerts, "vertex id out of range" );
00673     m_triangles[ triId * 3 + 2] = vertId;
00674 }
00675 
00676 inline osg::Vec3 WTriangleMesh::getTriVert( size_t triId, size_t vertNum )
00677 {
00678     WAssert( triId < m_countTriangles, "triangle id out of range" );
00679     return ( *m_verts )[ m_triangles[ triId * 3  + vertNum] ];
00680 }
00681 
00682 inline size_t WTriangleMesh::getTriVertId0( size_t triId ) const
00683 {
00684     WAssert( triId < m_countTriangles, "get tri vert id 0: triangle id out of range" );
00685     return m_triangles[triId * 3];
00686 }
00687 
00688 inline size_t WTriangleMesh::getTriVertId1( size_t triId ) const
00689 {
00690     WAssert( triId < m_countTriangles, "get tri vert id 1: triangle id out of range" );
00691     return m_triangles[triId * 3 + 1];
00692 }
00693 
00694 inline size_t WTriangleMesh::getTriVertId2( size_t triId ) const
00695 {
00696     WAssert( triId < m_countTriangles, "get tri vert id 2: triangle id out of range" );
00697     return m_triangles[triId * 3 + 2];
00698 }
00699 
00700 inline void WTriangleMesh::setVertex( size_t index, osg::Vec3 vert )
00701 {
00702     ( *m_verts )[index] = vert;
00703 }
00704 
00705 #endif  // WTRIANGLEMESH_H
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends