OpenWalnut  1.4.0
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/WPosition.h"
00035 #include "../common/math/linearAlgebra/WVectorFixed.h"
00036 #include "../common/WAssert.h"
00037 #include "../common/WColor.h"
00038 #include "../common/WTransferable.h"
00039 
00040 
00041 /**
00042  * Triangle mesh data structure allowing for convenient access of the elements.
00043  */
00044 class WTriangleMesh  : public WTransferable
00045 {
00046 friend class WTriangleMeshTest;
00047 public:
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      * \return the index of the vertex
00105      */
00106     size_t addVertex( osg::Vec3 vert );
00107 
00108     /**
00109      * adds a vertex position to the mesh
00110      *
00111      * \param x
00112      * \param y
00113      * \param z
00114      *
00115      * \return the index of the vertex
00116      */
00117     size_t addVertex( float x, float y, float z );
00118 
00119     /**
00120      * adds a vertex position to the mesh
00121      *
00122      * \param vert vertex to add
00123      * \return the index of the vertex
00124      */
00125     size_t addVertex( WPosition vert );
00126 
00127     /**
00128      * Adds a texture coordinate for the vertex.
00129      *
00130      * \param texCoord the texture coordinate
00131      */
00132     void addTextureCoordinate( osg::Vec3 texCoord );
00133 
00134     /**
00135      * Adds a texture coordinate for the vertex.
00136      *
00137      * \param x texture coordinate X
00138      * \param y texture coordinate Y
00139      * \param z texture coordinate Z
00140      */
00141     void addTextureCoordinate( float x, float y, float z );
00142 
00143     /**
00144      * adds a tringle to the mesh
00145      *
00146      * \param vert0 index of the first vertex
00147      * \param vert1 index of the second vertex
00148      * \param vert2 index of the third vertex
00149      */
00150     void addTriangle( size_t vert0, size_t vert1, size_t vert2 );
00151 
00152     /**
00153      * adds a tringle and its 3 vertexes  to the mesh
00154      *
00155      * \param vert0 position of the first vertex
00156      * \param vert1 position of the second vertex
00157      * \param vert2 position of the third vertex
00158      */
00159     void addTriangle( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
00160 
00161     /**
00162      * sets a vertex to a new position
00163      *
00164      * \param index
00165      * \param vert
00166      */
00167     void setVertex( size_t index, osg::Vec3 vert );
00168 
00169     /**
00170      * sets the normal for a given vertex
00171      *
00172      * \param index
00173      * \param normal
00174      */
00175     void setVertexNormal( size_t index, osg::Vec3 normal );
00176 
00177     /**
00178      * sets the normal for a given vertex
00179      *
00180      * \param index
00181      * \param x x coordinate
00182      * \param y y coordinate
00183      * \param z z coordinate
00184      */
00185     void setVertexNormal( size_t index, float x, float y, float z );
00186 
00187     /**
00188      * sets the normal for a given vertex
00189      *
00190      * \param index
00191      * \param normal
00192      */
00193     void setVertexNormal( size_t index, WPosition normal );
00194 
00195     /**
00196      * sets the color for a given vertex
00197      *
00198      * \param index
00199      * \param color
00200      */
00201     void setVertexColor( size_t index, osg::Vec4 color );
00202 
00203     /**
00204      * sets the color for a given triangle
00205      *
00206      * \param index
00207      * \param color
00208      */
00209     void setTriangleColor( size_t index, osg::Vec4 color );
00210 
00211     /**
00212      * Set a texture coordinate.
00213      *
00214      * \param index The id of the vertex to set the texture coord of.
00215      * \param texCoord The texture coordinate to use.
00216      */
00217     void setTextureCoord( std::size_t index, osg::Vec3 texCoord );
00218 
00219     /**
00220      * Return triangle colors
00221      *
00222      * \return OSG Vec4 Array of triangle colors
00223      */
00224     osg::ref_ptr< osg::Vec4Array > getTriangleColors() const;
00225 
00226     /**
00227      * getter
00228      *
00229      * \return pointer to the vertex array
00230      */
00231     osg::ref_ptr< osg::Vec3Array > getVertexArray();
00232 
00233     /**
00234      * Returns a const reference pointer to the vertex array.
00235      *
00236      * \return vertex array
00237      */
00238     osg::ref_ptr< const osg::Vec3Array > getVertexArray() const;
00239 
00240     /**
00241      * Returns a reference pointer to the texture coordinate array.
00242      *
00243      * \return texture coordinate array
00244      */
00245     osg::ref_ptr< osg::Vec3Array > getTextureCoordinateArray();
00246 
00247     /**
00248      * Returns a const reference pointer to the texture coordinate array.
00249      *
00250      * \return texture coordinate array
00251      */
00252     osg::ref_ptr< const osg::Vec3Array > getTextureCoordinateArray() const;
00253 
00254     /**
00255      * getter
00256      *
00257      * \param forceRecalc
00258      * \return pointer to the vertex normal array
00259      */
00260     osg::ref_ptr< osg::Vec3Array > getVertexNormalArray( bool forceRecalc = false );
00261 
00262     /**
00263      * getter
00264      *
00265      * \return pointer to the vertex color array
00266      */
00267     osg::ref_ptr< osg::Vec4Array > getVertexColorArray();
00268 
00269     /**
00270      * Returns a const reference to the vertex ids of the triangles.
00271      *
00272      * \return The triangle vertex id list
00273      */
00274     const std::vector< size_t >& getTriangles() const;
00275 
00276     /**
00277      * getter
00278      *
00279      * \param forceRecalc
00280      * \return pointer to the triangle normal array
00281      */
00282     osg::ref_ptr< osg::Vec3Array > getTriangleNormalArray( bool forceRecalc = false );
00283 
00284 
00285     /**
00286      * getter
00287      *
00288      * \param index
00289      * \return vertex
00290      */
00291     osg::Vec3 getVertex( size_t index ) const;
00292 
00293     /**
00294      * getter
00295      *
00296      * \param index
00297      * \return color
00298      */
00299     osg::Vec4 getVertColor( size_t index ) const;
00300 
00301     /**
00302      * getter
00303      *
00304      * \param triId
00305      * \param vertNum
00306      * \return vertex
00307      */
00308     osg::Vec3 getTriVert( size_t triId, size_t vertNum );
00309 
00310     /**
00311      * getter
00312      *
00313      * \param index
00314      * \return normal
00315      */
00316     WVector3d getNormal( size_t index );
00317 
00318     /**
00319      * getter
00320      *
00321      * \return number of vertices in the mesh
00322      */
00323     size_t vertSize() const;
00324 
00325     /**
00326      * getter
00327      *
00328      * \return number of triangles in the mesh
00329      */
00330     size_t triangleSize() const;
00331 
00332     /**
00333      * performs a loop subdivision on the triangle mesh
00334      */
00335     void doLoopSubD();
00336 
00337     /**
00338      * returns the id of the first vertex of a triangle
00339      *
00340      * \param triId id of the triangle
00341      * \return id of the vertex
00342      */
00343     size_t getTriVertId0( size_t triId ) const;
00344 
00345     /**
00346      * returns the id of the second vertex of a triangle
00347      *
00348      * \param triId id of the triangle
00349      * \return id of the vertex
00350      */
00351     size_t getTriVertId1( size_t triId ) const;
00352 
00353     /**
00354      * return the id of the third vertex of a triangle
00355      *
00356      * \param triId id of the triangle
00357      * \return id of the vertex
00358      */
00359     size_t getTriVertId2( size_t triId ) const;
00360 
00361     /**
00362      *  adds a mesh to the existing, no check for duplicate vertexes is performed, an additional
00363      *  vector may be specified to move the mesh to add
00364      *
00365      *  \param mesh
00366      *  \param xOff
00367      *  \param yOff
00368      *  \param zOff
00369      */
00370     void addMesh( boost::shared_ptr<WTriangleMesh> mesh, float xOff = 0., float yOff = 0., float zOff = 0. );
00371 
00372     /**
00373      *  moves the entire mesh to a new postion
00374      *
00375      *  \param xOff
00376      *  \param yOff
00377      *  \param zOff
00378      */
00379     void translateMesh( float xOff, float yOff, float zOff );
00380 
00381     /**
00382      * multiplies the vertex vectors of the mesh with a given number
00383      *
00384      * \param zoom
00385      */
00386     void zoomMesh( float zoom );
00387 
00388     /**
00389      * Checks if two meshes are exactly the same. Same number of triangles, and
00390      * points, and indices as well as same ordering. Keep in mind different
00391      * ordering might result in the same structure but is considered different
00392      * here.
00393      *
00394      * \param rhs The other mesh to compare with
00395      *
00396      * \return True if and only if both: vertices and triangles are exactly the same.
00397      */
00398     bool operator==( const WTriangleMesh& rhs ) const;
00399 
00400     /**
00401      * Rescale the vertex colors so that the maximum of all r, g and b values is 1
00402      */
00403     void rescaleVertexColors();
00404 
00405     /**
00406      * Implements the feature-preserving mesh smoothing algorithm of Jones et al.:
00407      *
00408      * "Non-Iterative, Feature-Preserving Mesh Smoothing", Jones, T.R., Durand, F.,
00409      * Desbrun, M., ACM Trans. Graph. (22), 2003, 943-949
00410      *
00411      * \param sigmaDistance The standard deviation for the spatial weight.
00412      * \param sigmaInfluence The standard deviation for the influence weight.
00413      */
00414     void performFeaturePreservingSmoothing( float sigmaDistance, float sigmaInfluence );
00415 
00416     /**
00417      * Estimates the normal curvatures and their principal directions for every vertex using
00418      * the algorithm of:
00419      *
00420      * DONG, Chen-shi; WANG, Guo-zhao. Curvatures estimation on triangular mesh. Journal of Zhejiang University SCIENCE, 2005, 6. Jg., Nr. 1, S. 128-136.
00421      */
00422     void estimateCurvature();
00423 
00424     /**
00425      * Retreive the main (maximum) curvature of a vertex.
00426      *
00427      * \param vtxId The id of the vertex.
00428      *
00429      * \return The estimated main normal curvature.
00430      */
00431     double getMainCurvature( std::size_t vtxId ) const;
00432 
00433     /**
00434      * Retreive the secondary (minimum) curvature of a vertex.
00435      *
00436      * \param vtxId The id of the vertex.
00437      *
00438      * \return The estimated secondary normal curvature.
00439      */
00440     double getSecondaryCurvature( std::size_t vtxId ) const;
00441 
00442     /**
00443      * Get the vector of main curvature values.
00444      *
00445      * \return The curvature values for all the vertices.
00446      */
00447     boost::shared_ptr< std::vector< float > > const& getMainCurvatures() const;
00448 
00449     /**
00450      * Get the vector of secondary curvature values.
00451      *
00452      * \return The curvature values for all the vertices.
00453      */
00454     boost::shared_ptr< std::vector< float > > const& getSecondaryCurvatures() const;
00455 
00456     /**
00457      * Retreive the 3d principal direction of curvature of a vertex.
00458      *
00459      * \param vtxId The id of the vertex.
00460      *
00461      * \return The first principal duirection.
00462      */
00463     osg::Vec3 getCurvatureMainPrincipalDirection( std::size_t vtxId ) const;
00464 
00465     /**
00466      * Retreive the 3d principal direction of curvature for the minimum normal curvature of a vertex.
00467      *
00468      * \param vtxId The id of the vertex.
00469      *
00470      * \return The second principal duirection.
00471      */
00472     osg::Vec3 getCurvatureSecondaryPrincipalDirection( std::size_t vtxId ) const;
00473 
00474     /**
00475      * Retreive the array of principal directions e.g. for use as texture coords.
00476      *
00477      * \return The full array of principal directions.
00478      */
00479     osg::ref_ptr< osg::Vec3Array > getMainPrincipalCurvatureDirectionArray();
00480 
00481     /**
00482      * Retreive the array of principal directions e.g. for use as texture coords.
00483      *
00484      * \return The full array of principal directions.
00485      */
00486     osg::ref_ptr< osg::Vec3Array > getSecondaryPrincipalCurvatureDirectionArray();
00487 
00488     /**
00489      * recalculates the vertex normals
00490      */
00491     void recalcVertNormals();
00492 
00493     /**
00494      * Set this to true to force automatic normal calculation. Set it to false if you specify your own normals.
00495      *
00496      * \param autoRecalc auto normal calculation.
00497      */
00498     void setAutoRecalcNormals( bool autoRecalc = true );
00499 
00500 protected:
00501     static boost::shared_ptr< WPrototyped > m_prototype; //!< The prototype as singleton.
00502 private:
00503     /**
00504      * we don't allow the standard constructor
00505      */
00506     WTriangleMesh();
00507 
00508     /**
00509      * removes a vertex from the vertex array, if any triangles still index that vertex they will be
00510      * removed if forceRemoveTriangle is true
00511      *
00512      * \param index the index of the vertex to remove
00513      */
00514     void removeVertex( size_t index );
00515 
00516     /**
00517      * removes a triangle from the mesh
00518      *
00519      * \param index the triangle to remove
00520      */
00521     void removeTriangle( size_t index );
00522 
00523     /**
00524      * calculates a normal from the 3 points in space defining a triangle
00525      *
00526      * \param triangle
00527      *
00528      * \return the normal of the triangle
00529      */
00530     osg::Vec3 calcTriangleNormal( size_t triangle );
00531 
00532     /**
00533      * calculates a normal from the 3 points in space
00534      *
00535      * \param vert0 vertex 1
00536      * \param vert1 vertex 2
00537      * \param vert2 vertex 3
00538      *
00539      * \return the normal of the plane defined by these three points
00540      */
00541     osg::Vec3 calcNormal( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
00542 
00543     /**
00544      * updates the list for which vertexes appear in which triangle
00545      */
00546     void updateVertsInTriangles();
00547 
00548     /**
00549      * calculates neighbor information for triangles
00550      */
00551     void calcNeighbors();
00552 
00553     /**
00554      * returns the triangle index of a triangle neighboring a given edge of a vertex
00555      *
00556      * \param coVert1
00557      * \param coVert2
00558      * \param triangleNum
00559      *
00560      * \return the number of the neighboring triangle.
00561      */
00562     size_t getNeighbor( const size_t coVert1, const size_t coVert2, const size_t triangleNum );
00563 
00564     /**
00565      * higher level access function to the triangle vector, sets the first vertex of a triangle to
00566      * a given vertex id
00567      *
00568      * \param triId the id of the triangle to modify
00569      * \param vertId new id of the first vertex
00570      */
00571     void setTriVert0( size_t triId, size_t vertId );
00572 
00573     /**
00574      * higher level access function to the triangle vector, sets the second vertex of a triangle to
00575      * a given vertex id
00576      *
00577      * \param triId the id of the triangle to modify
00578      * \param vertId new id of the second vertex
00579      */
00580     void setTriVert1( size_t triId, size_t vertId );
00581 
00582     /**
00583      * higher level access function to the triangle vector, sets the third vertex of a triangle to
00584      * a given vertex id
00585      *
00586      * \param triId the id of the triangle to modify
00587      * \param vertId new id of the third vertex
00588      */
00589     void setTriVert2( size_t triId, size_t vertId );
00590 
00591 
00592     // the next functions are helper functions for the loop subdivision algorithm and exist only for that
00593     // purpose, for more information read http://research.microsoft.com/en-us/um/people/cloop/thesis.pdf
00594 
00595 
00596     /**
00597      * changes the vertex ids of a triangle
00598      *
00599      * \param triId
00600      * \param vertId1
00601      * \param vertId2
00602      * \param vertId3
00603      */
00604     void loopSetTriangle( size_t triId, size_t vertId1, size_t vertId2, size_t vertId3 );
00605 
00606     /**
00607      * erases a triangle from the vertexe's list of triangles it is part of
00608      *
00609      * \param triId
00610      * \param vertId
00611      */
00612     void loopEraseTriangleFromVertex( size_t triId, size_t vertId );
00613 
00614     /**
00615      * calculates the new position of a vertex depending on it's location in the grid and number of neighbors
00616      *
00617      * \param vertId the vertex id
00618      * \return new position in 3D space
00619      */
00620     osg::Vec3 loopCalcNewPosition( size_t vertId );
00621 
00622     /**
00623      * inserts the center triangle in a given triangle,
00624      *
00625      * \param triId the triangle id
00626      */
00627     void loopInsertCenterTriangle( size_t triId );
00628 
00629     /**
00630      * inserts the 3 corner triangles in a given triangle
00631      *
00632      * \param triId the triangle id
00633      */
00634     void loopInsertCornerTriangles( size_t triId );
00635 
00636     /**
00637      * calculates the vertex id for a given edge, inserts a new vertex of none exists yet
00638      *
00639      * \param triId the triangle id
00640      * \param edgeV1
00641      * \param edgeV2
00642      * \param V3
00643      * \return index of the vertex
00644      */
00645     size_t loopCalcEdgeVert( size_t triId, size_t edgeV1, size_t edgeV2, size_t V3 );
00646 
00647     /**
00648      * loop helper function
00649      * \param n
00650      * \return alpha
00651      */
00652     double loopGetAlpha( int n );
00653 
00654     /**
00655      * returns the id of the next vertex int he triangle
00656      *
00657      * \param triNum id of the triangle
00658      * \param vertNum id of the vertex
00659      * \return id of the next vertex
00660      */
00661     size_t loopGetNextVertex( size_t triNum, size_t vertNum );
00662 
00663     /**
00664      * returns the id of the third vertex of a triangle for two given vertexes
00665      *
00666      * \param coVert1
00667      * \param coVert2
00668      * \param triangleNum
00669      * \return id of the third vertex
00670      */
00671     size_t loopGetThirdVert( size_t coVert1, size_t coVert2, size_t triangleNum );
00672 
00673     /**
00674      * Performs the first pass of the feature-preserving smoothing, only changing the triangle
00675      * normals.
00676      *
00677      * \param sigmaDistance The standard deviation of the spatial weights.
00678      * \param sigmaInfluence The standard deviation of the influence weights.
00679      */
00680     void performFeaturePreservingSmoothingMollificationPass( float sigmaDistance, float sigmaInfluence );
00681 
00682     /**
00683      * Performs the second pass of the feature-preserving smoothing. This calculates new
00684      * smoothed vertex positions and updates the normals accordingly. Triangle information and colors
00685      * stay the same.
00686      *
00687      * \param sigmaDistance The standard deviation of the spatial weights.
00688      * \param sigmaInfluence The standard deviation of the influence weights.
00689      */
00690     void performFeaturePreservingSmoothingVertexPass( float sigmaDistance, float sigmaInfluence );
00691 
00692     /**
00693      * Calculates Eq. 3 of:
00694      *
00695      * "Non-Iterative, Feature-Preserving Mesh Smoothing", Jones, T.R., Durand, F.,
00696      * Desbrun, M., ACM Trans. Graph. (22), 2003, 943-949
00697      *
00698      * \param vtx The id of the vertex to calculate the new position for.
00699      * \param sigmaDistance The standard deviation of the spatial weights.
00700      * \param sigmaInfluence The standard deviation of the influence weights.
00701      * \param mollify Whether this is a mollification pass (simple position estimates) or not.
00702      *
00703      * \return The smoothed vertex position.
00704      */
00705     osg::Vec3 estimateSmoothedVertexPosition( std::size_t vtx, float sigmaDistance, float sigmaInfluence, bool mollify );
00706 
00707     /**
00708      * Calculates the center position of a triangle.
00709      *
00710      * \param triIdx The id of the triangle to calculate the center of.
00711      *
00712      * \return The center of the triangle.
00713      */
00714     osg::Vec3 calcTriangleCenter( std::size_t triIdx ) const;
00715 
00716     /**
00717      * Calculates the area of a triangle.
00718      *
00719      * \param triIdx The id of the triangle to calculate the area of.
00720      *
00721      * \return The area of the triangle.
00722      */
00723     float calcTriangleArea( std::size_t triIdx ) const;
00724 
00725     /**
00726      * Calculates the angle between two NORMALIZED vectors. Asserts in debug mode, in release mode
00727      * when called with non-normalized vectors, results are undefined.
00728      *
00729      * \param v1 The first NORMALIZED vector.
00730      * \param v2 The second NORMALIZED vector.
00731      *
00732      * \return The angle between the vectors in radians.
00733      */
00734     double calcAngleBetweenNormalizedVectors( osg::Vec3 const& v1, osg::Vec3 const& v2 );
00735 
00736     size_t m_countVerts; //!< number of vertexes in the mesh
00737 
00738     size_t m_countTriangles; //!< number of triangles in the mesh
00739 
00740     bool m_meshDirty; //!< flag indicating a change took place which requires a recalculation of components
00741 
00742     bool m_autoNormal; //!< flag denoting whether normals should be calculated automatically.
00743 
00744     bool m_neighborsCalculated; //!< flag indicating whether the neighbor information has been calculated yet
00745 
00746     //! Indicates whether the curvature and its principal directions have been calculated.
00747     bool m_curvatureCalculated;
00748 
00749     osg::ref_ptr< osg::Vec3Array > m_verts; //!< array containing the vertices
00750 
00751     osg::ref_ptr< osg::Vec3Array > m_textureCoordinates; //!< array containing the texture coordinates
00752 
00753     osg::ref_ptr< osg::Vec3Array > m_vertNormals; //!< array containing the vertex normals
00754 
00755     osg::ref_ptr< osg::Vec4Array > m_vertColors; //!< array containing vertex colors
00756 
00757     std::vector< size_t > m_triangles; //!< array containing the triangles
00758 
00759     osg::ref_ptr< osg::Vec3Array > m_triangleNormals; //!< array containing the triangle normals
00760 
00761     osg::ref_ptr< osg::Vec4Array > m_triangleColors; //!< array containing the triangle colors
00762 
00763     // helper structures
00764     std::vector < std::vector< size_t > > m_vertexIsInTriangle; //!< for each vertex, list of triangles it is part of
00765 
00766     std::vector< std::vector< size_t > > m_triangleNeighbors; //!< edge neighbors for each triangle
00767 
00768     //! Stores the maximum normal curvature (for the first principal direction) for each vertex.
00769     boost::shared_ptr< std::vector< float > > m_mainNormalCurvature;
00770 
00771     //! Stores the minimum normal curvature (for the second principal direction) for each vertex.
00772     boost::shared_ptr< std::vector< float > > m_secondaryNormalCurvature;
00773 
00774     //! Stores the first principal curvature direction for each vertex.
00775     osg::ref_ptr< osg::Vec3Array > m_mainCurvaturePrincipalDirection;
00776 
00777     //! Stores the second principal curvature direction for each vertex.
00778     osg::ref_ptr< osg::Vec3Array > m_secondaryCurvaturePrincipalDirection;
00779 
00780     size_t m_numTriVerts; //!< stores the number of vertexes before the loop subdivion is run, needed by the loop algorithm
00781 
00782     size_t m_numTriFaces; //!< stores the number of triangles before the loop subdivion is run, needed by the loop algorithm
00783 };
00784 
00785 /**
00786  * TriangleMesh utils
00787  */
00788 namespace tm_utils
00789 {
00790     /**
00791      * Decompose the given mesh into connected components.
00792      *
00793      * \param mesh The triangle mesh to decompose
00794      *
00795      * \return List of components where each of them is a WTriangleMesh again.
00796      */
00797     boost::shared_ptr< std::list< boost::shared_ptr< WTriangleMesh > > > componentDecomposition( const WTriangleMesh& mesh );
00798 
00799     /**
00800      * Prints for each mesh \#vertices and \#triangles, as well as each triangle with its positions. No point IDs are printed.
00801      *
00802      * \param os Output stream to print on.
00803      * \param rhs The mesh instance.
00804      *
00805      * \return The output stream again for further usage.
00806      */
00807     std::ostream& operator<<( std::ostream& os, const WTriangleMesh& rhs );
00808 }
00809 
00810 inline bool WTriangleMesh::operator==( const WTriangleMesh& rhs ) const
00811 {
00812     return std::equal( m_verts->begin(), m_verts->end(), rhs.m_verts->begin() ) &&
00813            std::equal( m_triangles.begin(), m_triangles.end(), rhs.m_triangles.begin() );
00814 }
00815 
00816 inline void WTriangleMesh::addTextureCoordinate( osg::Vec3 texCoord )
00817 {
00818     ( *m_textureCoordinates )[m_countVerts-1] = texCoord;
00819 }
00820 
00821 inline void WTriangleMesh::addTextureCoordinate( float x, float y, float z )
00822 {
00823     addTextureCoordinate( osg::Vec3( x, y, z ) );
00824 }
00825 
00826 inline size_t WTriangleMesh::addVertex( osg::Vec3 vert )
00827 {
00828     if( ( *m_verts ).size() == m_countVerts )
00829     {
00830         ( *m_verts ).resize( m_countVerts + 1 );
00831     }
00832     if( ( *m_textureCoordinates ).size() == m_countVerts )
00833     {
00834         ( *m_textureCoordinates ).resize( m_countVerts + 1 );
00835     }
00836     if( ( *m_vertColors ).size() == m_countVerts )
00837     {
00838         ( *m_vertColors ).resize( m_countVerts + 1 );
00839         ( *m_vertColors )[ m_countVerts ] = osg::Vec4( 1.0, 1.0, 1.0, 1.0 );
00840     }
00841     if( ( *m_vertNormals ).size() == m_countVerts )
00842     {
00843         ( *m_vertNormals ).resize( m_countVerts + 1 );
00844     }
00845 
00846     size_t index = m_countVerts;
00847     ( *m_verts )[index] = vert;
00848     ( *m_vertNormals )[index] = osg::Vec3( 1.0, 1.0, 1.0 );
00849 
00850     ++m_countVerts;
00851     return index;
00852 }
00853 
00854 inline const std::string WTriangleMesh::getName() const
00855 {
00856     return "WTriangleMesh";
00857 }
00858 
00859 inline const std::string WTriangleMesh::getDescription() const
00860 {
00861     return "Triangle mesh data structure allowing for convenient access of the elements.";
00862 }
00863 
00864 inline void WTriangleMesh::setTriVert0( size_t triId, size_t vertId )
00865 {
00866     WAssert( triId < m_countTriangles, "set tri vert 0: triangle id out of range" );
00867     WAssert( vertId < m_countVerts, "vertex id out of range" );
00868     m_triangles[ triId * 3 ] = vertId;
00869 }
00870 
00871 inline void WTriangleMesh::setTriVert1( size_t triId, size_t vertId )
00872 {
00873     WAssert( triId < m_countTriangles, "set tri vert 1: triangle id out of range" );
00874     WAssert( vertId < m_countVerts, "vertex id out of range" );
00875     m_triangles[ triId * 3 + 1] = vertId;
00876 }
00877 
00878 inline void WTriangleMesh::setTriVert2( size_t triId, size_t vertId )
00879 {
00880     WAssert( triId < m_countTriangles, "set tri vert 2: triangle id out of range" );
00881     WAssert( vertId < m_countVerts, "vertex id out of range" );
00882     m_triangles[ triId * 3 + 2] = vertId;
00883 }
00884 
00885 inline osg::Vec3 WTriangleMesh::getTriVert( size_t triId, size_t vertNum )
00886 {
00887     WAssert( triId < m_countTriangles, "triangle id out of range" );
00888     return ( *m_verts )[ m_triangles[ triId * 3  + vertNum] ];
00889 }
00890 
00891 inline size_t WTriangleMesh::getTriVertId0( size_t triId ) const
00892 {
00893     WAssert( triId < m_countTriangles, "get tri vert id 0: triangle id out of range" );
00894     return m_triangles[triId * 3];
00895 }
00896 
00897 inline size_t WTriangleMesh::getTriVertId1( size_t triId ) const
00898 {
00899     WAssert( triId < m_countTriangles, "get tri vert id 1: triangle id out of range" );
00900     return m_triangles[triId * 3 + 1];
00901 }
00902 
00903 inline size_t WTriangleMesh::getTriVertId2( size_t triId ) const
00904 {
00905     WAssert( triId < m_countTriangles, "get tri vert id 2: triangle id out of range" );
00906     return m_triangles[triId * 3 + 2];
00907 }
00908 
00909 inline void WTriangleMesh::setVertex( size_t index, osg::Vec3 vert )
00910 {
00911     ( *m_verts )[index] = vert;
00912 }
00913 
00914 #endif  // WTRIANGLEMESH_H