OpenWalnut  1.4.0
WTriangleMesh.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WTRIANGLEMESH_H
26 #define WTRIANGLEMESH_H
27 
28 #include <list>
29 #include <string>
30 #include <vector>
31 
32 #include <osg/Geode>
33 
34 #include "../common/math/linearAlgebra/WPosition.h"
35 #include "../common/math/linearAlgebra/WVectorFixed.h"
36 #include "../common/WAssert.h"
37 #include "../common/WColor.h"
38 #include "../common/WTransferable.h"
39 
40 
41 /**
42  * Triangle mesh data structure allowing for convenient access of the elements.
43  */
45 {
46 friend class WTriangleMeshTest;
47 public:
48  /**
49  * Shared pointer
50  */
51  typedef boost::shared_ptr< WTriangleMesh > SPtr;
52 
53  /**
54  * Const shared pointer
55  */
56  typedef boost::shared_ptr< const WTriangleMesh > ConstSPtr;
57 
58  /**
59  * constructor that already reserves space for a given number of triangles and vertexes
60  *
61  * \param vertNum
62  * \param triangleNum
63  */
64  WTriangleMesh( size_t vertNum, size_t triangleNum );
65 
66  /**
67  * Constructs a new mesh out of the given vertices and triangles.
68  *
69  * \param vertices Vec3Array storing all vertices
70  * \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
71  */
72  WTriangleMesh( osg::ref_ptr< osg::Vec3Array > vertices, const std::vector< size_t >& triangles );
73 
74  /**
75  * destructor
76  */
77  virtual ~WTriangleMesh();
78 
79  /**
80  * Returns a prototype instantiated with the true type of the deriving class.
81  *
82  * \return the prototype.
83  */
84  static boost::shared_ptr< WPrototyped > getPrototype();
85 
86  /**
87  * Gets the name of this prototype.
88  *
89  * \return the name.
90  */
91  virtual const std::string getName() const;
92 
93  /**
94  * Gets the description for this prototype.
95  *
96  * \return the description
97  */
98  virtual const std::string getDescription() const;
99 
100  /**
101  * adds a vertex position to the mesh
102  *
103  * \param vert
104  * \return the index of the vertex
105  */
106  size_t addVertex( osg::Vec3 vert );
107 
108  /**
109  * adds a vertex position to the mesh
110  *
111  * \param x
112  * \param y
113  * \param z
114  *
115  * \return the index of the vertex
116  */
117  size_t addVertex( float x, float y, float z );
118 
119  /**
120  * adds a vertex position to the mesh
121  *
122  * \param vert vertex to add
123  * \return the index of the vertex
124  */
125  size_t addVertex( WPosition vert );
126 
127  /**
128  * Adds a texture coordinate for the vertex.
129  *
130  * \param texCoord the texture coordinate
131  */
132  void addTextureCoordinate( osg::Vec3 texCoord );
133 
134  /**
135  * Adds a texture coordinate for the vertex.
136  *
137  * \param x texture coordinate X
138  * \param y texture coordinate Y
139  * \param z texture coordinate Z
140  */
141  void addTextureCoordinate( float x, float y, float z );
142 
143  /**
144  * adds a tringle to the mesh
145  *
146  * \param vert0 index of the first vertex
147  * \param vert1 index of the second vertex
148  * \param vert2 index of the third vertex
149  */
150  void addTriangle( size_t vert0, size_t vert1, size_t vert2 );
151 
152  /**
153  * adds a tringle and its 3 vertexes to the mesh
154  *
155  * \param vert0 position of the first vertex
156  * \param vert1 position of the second vertex
157  * \param vert2 position of the third vertex
158  */
159  void addTriangle( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
160 
161  /**
162  * sets a vertex to a new position
163  *
164  * \param index
165  * \param vert
166  */
167  void setVertex( size_t index, osg::Vec3 vert );
168 
169  /**
170  * sets the normal for a given vertex
171  *
172  * \param index
173  * \param normal
174  */
175  void setVertexNormal( size_t index, osg::Vec3 normal );
176 
177  /**
178  * sets the normal for a given vertex
179  *
180  * \param index
181  * \param x x coordinate
182  * \param y y coordinate
183  * \param z z coordinate
184  */
185  void setVertexNormal( size_t index, float x, float y, float z );
186 
187  /**
188  * sets the normal for a given vertex
189  *
190  * \param index
191  * \param normal
192  */
193  void setVertexNormal( size_t index, WPosition normal );
194 
195  /**
196  * sets the color for a given vertex
197  *
198  * \param index
199  * \param color
200  */
201  void setVertexColor( size_t index, osg::Vec4 color );
202 
203  /**
204  * sets the color for a given triangle
205  *
206  * \param index
207  * \param color
208  */
209  void setTriangleColor( size_t index, osg::Vec4 color );
210 
211  /**
212  * Set a texture coordinate.
213  *
214  * \param index The id of the vertex to set the texture coord of.
215  * \param texCoord The texture coordinate to use.
216  */
217  void setTextureCoord( std::size_t index, osg::Vec3 texCoord );
218 
219  /**
220  * Return triangle colors
221  *
222  * \return OSG Vec4 Array of triangle colors
223  */
224  osg::ref_ptr< osg::Vec4Array > getTriangleColors() const;
225 
226  /**
227  * getter
228  *
229  * \return pointer to the vertex array
230  */
231  osg::ref_ptr< osg::Vec3Array > getVertexArray();
232 
233  /**
234  * Returns a const reference pointer to the vertex array.
235  *
236  * \return vertex array
237  */
238  osg::ref_ptr< const osg::Vec3Array > getVertexArray() const;
239 
240  /**
241  * Returns a reference pointer to the texture coordinate array.
242  *
243  * \return texture coordinate array
244  */
245  osg::ref_ptr< osg::Vec3Array > getTextureCoordinateArray();
246 
247  /**
248  * Returns a const reference pointer to the texture coordinate array.
249  *
250  * \return texture coordinate array
251  */
252  osg::ref_ptr< const osg::Vec3Array > getTextureCoordinateArray() const;
253 
254  /**
255  * getter
256  *
257  * \param forceRecalc
258  * \return pointer to the vertex normal array
259  */
260  osg::ref_ptr< osg::Vec3Array > getVertexNormalArray( bool forceRecalc = false );
261 
262  /**
263  * getter
264  *
265  * \return pointer to the vertex color array
266  */
267  osg::ref_ptr< osg::Vec4Array > getVertexColorArray();
268 
269  /**
270  * Returns a const reference to the vertex ids of the triangles.
271  *
272  * \return The triangle vertex id list
273  */
274  const std::vector< size_t >& getTriangles() const;
275 
276  /**
277  * getter
278  *
279  * \param forceRecalc
280  * \return pointer to the triangle normal array
281  */
282  osg::ref_ptr< osg::Vec3Array > getTriangleNormalArray( bool forceRecalc = false );
283 
284 
285  /**
286  * getter
287  *
288  * \param index
289  * \return vertex
290  */
291  osg::Vec3 getVertex( size_t index ) const;
292 
293  /**
294  * getter
295  *
296  * \param index
297  * \return color
298  */
299  osg::Vec4 getVertColor( size_t index ) const;
300 
301  /**
302  * getter
303  *
304  * \param triId
305  * \param vertNum
306  * \return vertex
307  */
308  osg::Vec3 getTriVert( size_t triId, size_t vertNum );
309 
310  /**
311  * getter
312  *
313  * \param index
314  * \return normal
315  */
316  WVector3d getNormal( size_t index );
317 
318  /**
319  * getter
320  *
321  * \return number of vertices in the mesh
322  */
323  size_t vertSize() const;
324 
325  /**
326  * getter
327  *
328  * \return number of triangles in the mesh
329  */
330  size_t triangleSize() const;
331 
332  /**
333  * performs a loop subdivision on the triangle mesh
334  */
335  void doLoopSubD();
336 
337  /**
338  * returns the id of the first vertex of a triangle
339  *
340  * \param triId id of the triangle
341  * \return id of the vertex
342  */
343  size_t getTriVertId0( size_t triId ) const;
344 
345  /**
346  * returns the id of the second vertex of a triangle
347  *
348  * \param triId id of the triangle
349  * \return id of the vertex
350  */
351  size_t getTriVertId1( size_t triId ) const;
352 
353  /**
354  * return the id of the third vertex of a triangle
355  *
356  * \param triId id of the triangle
357  * \return id of the vertex
358  */
359  size_t getTriVertId2( size_t triId ) const;
360 
361  /**
362  * adds a mesh to the existing, no check for duplicate vertexes is performed, an additional
363  * vector may be specified to move the mesh to add
364  *
365  * \param mesh
366  * \param xOff
367  * \param yOff
368  * \param zOff
369  */
370  void addMesh( boost::shared_ptr<WTriangleMesh> mesh, float xOff = 0., float yOff = 0., float zOff = 0. );
371 
372  /**
373  * moves the entire mesh to a new postion
374  *
375  * \param xOff
376  * \param yOff
377  * \param zOff
378  */
379  void translateMesh( float xOff, float yOff, float zOff );
380 
381  /**
382  * multiplies the vertex vectors of the mesh with a given number
383  *
384  * \param zoom
385  */
386  void zoomMesh( float zoom );
387 
388  /**
389  * Checks if two meshes are exactly the same. Same number of triangles, and
390  * points, and indices as well as same ordering. Keep in mind different
391  * ordering might result in the same structure but is considered different
392  * here.
393  *
394  * \param rhs The other mesh to compare with
395  *
396  * \return True if and only if both: vertices and triangles are exactly the same.
397  */
398  bool operator==( const WTriangleMesh& rhs ) const;
399 
400  /**
401  * Rescale the vertex colors so that the maximum of all r, g and b values is 1
402  */
403  void rescaleVertexColors();
404 
405  /**
406  * Implements the feature-preserving mesh smoothing algorithm of Jones et al.:
407  *
408  * "Non-Iterative, Feature-Preserving Mesh Smoothing", Jones, T.R., Durand, F.,
409  * Desbrun, M., ACM Trans. Graph. (22), 2003, 943-949
410  *
411  * \param sigmaDistance The standard deviation for the spatial weight.
412  * \param sigmaInfluence The standard deviation for the influence weight.
413  */
414  void performFeaturePreservingSmoothing( float sigmaDistance, float sigmaInfluence );
415 
416  /**
417  * Estimates the normal curvatures and their principal directions for every vertex using
418  * the algorithm of:
419  *
420  * DONG, Chen-shi; WANG, Guo-zhao. Curvatures estimation on triangular mesh. Journal of Zhejiang University SCIENCE, 2005, 6. Jg., Nr. 1, S. 128-136.
421  */
422  void estimateCurvature();
423 
424  /**
425  * Retreive the main (maximum) curvature of a vertex.
426  *
427  * \param vtxId The id of the vertex.
428  *
429  * \return The estimated main normal curvature.
430  */
431  double getMainCurvature( std::size_t vtxId ) const;
432 
433  /**
434  * Retreive the secondary (minimum) curvature of a vertex.
435  *
436  * \param vtxId The id of the vertex.
437  *
438  * \return The estimated secondary normal curvature.
439  */
440  double getSecondaryCurvature( std::size_t vtxId ) const;
441 
442  /**
443  * Get the vector of main curvature values.
444  *
445  * \return The curvature values for all the vertices.
446  */
447  boost::shared_ptr< std::vector< float > > const& getMainCurvatures() const;
448 
449  /**
450  * Get the vector of secondary curvature values.
451  *
452  * \return The curvature values for all the vertices.
453  */
454  boost::shared_ptr< std::vector< float > > const& getSecondaryCurvatures() const;
455 
456  /**
457  * Retreive the 3d principal direction of curvature of a vertex.
458  *
459  * \param vtxId The id of the vertex.
460  *
461  * \return The first principal duirection.
462  */
463  osg::Vec3 getCurvatureMainPrincipalDirection( std::size_t vtxId ) const;
464 
465  /**
466  * Retreive the 3d principal direction of curvature for the minimum normal curvature of a vertex.
467  *
468  * \param vtxId The id of the vertex.
469  *
470  * \return The second principal duirection.
471  */
472  osg::Vec3 getCurvatureSecondaryPrincipalDirection( std::size_t vtxId ) const;
473 
474  /**
475  * Retreive the array of principal directions e.g. for use as texture coords.
476  *
477  * \return The full array of principal directions.
478  */
479  osg::ref_ptr< osg::Vec3Array > getMainPrincipalCurvatureDirectionArray();
480 
481  /**
482  * Retreive the array of principal directions e.g. for use as texture coords.
483  *
484  * \return The full array of principal directions.
485  */
486  osg::ref_ptr< osg::Vec3Array > getSecondaryPrincipalCurvatureDirectionArray();
487 
488  /**
489  * recalculates the vertex normals
490  */
491  void recalcVertNormals();
492 
493  /**
494  * Set this to true to force automatic normal calculation. Set it to false if you specify your own normals.
495  *
496  * \param autoRecalc auto normal calculation.
497  */
498  void setAutoRecalcNormals( bool autoRecalc = true );
499 
500 protected:
501  static boost::shared_ptr< WPrototyped > m_prototype; //!< The prototype as singleton.
502 private:
503  /**
504  * we don't allow the standard constructor
505  */
506  WTriangleMesh();
507 
508  /**
509  * removes a vertex from the vertex array, if any triangles still index that vertex they will be
510  * removed if forceRemoveTriangle is true
511  *
512  * \param index the index of the vertex to remove
513  */
514  void removeVertex( size_t index );
515 
516  /**
517  * removes a triangle from the mesh
518  *
519  * \param index the triangle to remove
520  */
521  void removeTriangle( size_t index );
522 
523  /**
524  * calculates a normal from the 3 points in space defining a triangle
525  *
526  * \param triangle
527  *
528  * \return the normal of the triangle
529  */
530  osg::Vec3 calcTriangleNormal( size_t triangle );
531 
532  /**
533  * calculates a normal from the 3 points in space
534  *
535  * \param vert0 vertex 1
536  * \param vert1 vertex 2
537  * \param vert2 vertex 3
538  *
539  * \return the normal of the plane defined by these three points
540  */
541  osg::Vec3 calcNormal( osg::Vec3 vert0, osg::Vec3 vert1, osg::Vec3 vert2 );
542 
543  /**
544  * updates the list for which vertexes appear in which triangle
545  */
546  void updateVertsInTriangles();
547 
548  /**
549  * calculates neighbor information for triangles
550  */
551  void calcNeighbors();
552 
553  /**
554  * returns the triangle index of a triangle neighboring a given edge of a vertex
555  *
556  * \param coVert1
557  * \param coVert2
558  * \param triangleNum
559  *
560  * \return the number of the neighboring triangle.
561  */
562  size_t getNeighbor( const size_t coVert1, const size_t coVert2, const size_t triangleNum );
563 
564  /**
565  * higher level access function to the triangle vector, sets the first vertex of a triangle to
566  * a given vertex id
567  *
568  * \param triId the id of the triangle to modify
569  * \param vertId new id of the first vertex
570  */
571  void setTriVert0( size_t triId, size_t vertId );
572 
573  /**
574  * higher level access function to the triangle vector, sets the second vertex of a triangle to
575  * a given vertex id
576  *
577  * \param triId the id of the triangle to modify
578  * \param vertId new id of the second vertex
579  */
580  void setTriVert1( size_t triId, size_t vertId );
581 
582  /**
583  * higher level access function to the triangle vector, sets the third vertex of a triangle to
584  * a given vertex id
585  *
586  * \param triId the id of the triangle to modify
587  * \param vertId new id of the third vertex
588  */
589  void setTriVert2( size_t triId, size_t vertId );
590 
591 
592  // the next functions are helper functions for the loop subdivision algorithm and exist only for that
593  // purpose, for more information read http://research.microsoft.com/en-us/um/people/cloop/thesis.pdf
594 
595 
596  /**
597  * changes the vertex ids of a triangle
598  *
599  * \param triId
600  * \param vertId1
601  * \param vertId2
602  * \param vertId3
603  */
604  void loopSetTriangle( size_t triId, size_t vertId1, size_t vertId2, size_t vertId3 );
605 
606  /**
607  * erases a triangle from the vertexe's list of triangles it is part of
608  *
609  * \param triId
610  * \param vertId
611  */
612  void loopEraseTriangleFromVertex( size_t triId, size_t vertId );
613 
614  /**
615  * calculates the new position of a vertex depending on it's location in the grid and number of neighbors
616  *
617  * \param vertId the vertex id
618  * \return new position in 3D space
619  */
620  osg::Vec3 loopCalcNewPosition( size_t vertId );
621 
622  /**
623  * inserts the center triangle in a given triangle,
624  *
625  * \param triId the triangle id
626  */
627  void loopInsertCenterTriangle( size_t triId );
628 
629  /**
630  * inserts the 3 corner triangles in a given triangle
631  *
632  * \param triId the triangle id
633  */
634  void loopInsertCornerTriangles( size_t triId );
635 
636  /**
637  * calculates the vertex id for a given edge, inserts a new vertex of none exists yet
638  *
639  * \param triId the triangle id
640  * \param edgeV1
641  * \param edgeV2
642  * \param V3
643  * \return index of the vertex
644  */
645  size_t loopCalcEdgeVert( size_t triId, size_t edgeV1, size_t edgeV2, size_t V3 );
646 
647  /**
648  * loop helper function
649  * \param n
650  * \return alpha
651  */
652  double loopGetAlpha( int n );
653 
654  /**
655  * returns the id of the next vertex int he triangle
656  *
657  * \param triNum id of the triangle
658  * \param vertNum id of the vertex
659  * \return id of the next vertex
660  */
661  size_t loopGetNextVertex( size_t triNum, size_t vertNum );
662 
663  /**
664  * returns the id of the third vertex of a triangle for two given vertexes
665  *
666  * \param coVert1
667  * \param coVert2
668  * \param triangleNum
669  * \return id of the third vertex
670  */
671  size_t loopGetThirdVert( size_t coVert1, size_t coVert2, size_t triangleNum );
672 
673  /**
674  * Performs the first pass of the feature-preserving smoothing, only changing the triangle
675  * normals.
676  *
677  * \param sigmaDistance The standard deviation of the spatial weights.
678  * \param sigmaInfluence The standard deviation of the influence weights.
679  */
680  void performFeaturePreservingSmoothingMollificationPass( float sigmaDistance, float sigmaInfluence );
681 
682  /**
683  * Performs the second pass of the feature-preserving smoothing. This calculates new
684  * smoothed vertex positions and updates the normals accordingly. Triangle information and colors
685  * stay the same.
686  *
687  * \param sigmaDistance The standard deviation of the spatial weights.
688  * \param sigmaInfluence The standard deviation of the influence weights.
689  */
690  void performFeaturePreservingSmoothingVertexPass( float sigmaDistance, float sigmaInfluence );
691 
692  /**
693  * Calculates Eq. 3 of:
694  *
695  * "Non-Iterative, Feature-Preserving Mesh Smoothing", Jones, T.R., Durand, F.,
696  * Desbrun, M., ACM Trans. Graph. (22), 2003, 943-949
697  *
698  * \param vtx The id of the vertex to calculate the new position for.
699  * \param sigmaDistance The standard deviation of the spatial weights.
700  * \param sigmaInfluence The standard deviation of the influence weights.
701  * \param mollify Whether this is a mollification pass (simple position estimates) or not.
702  *
703  * \return The smoothed vertex position.
704  */
705  osg::Vec3 estimateSmoothedVertexPosition( std::size_t vtx, float sigmaDistance, float sigmaInfluence, bool mollify );
706 
707  /**
708  * Calculates the center position of a triangle.
709  *
710  * \param triIdx The id of the triangle to calculate the center of.
711  *
712  * \return The center of the triangle.
713  */
714  osg::Vec3 calcTriangleCenter( std::size_t triIdx ) const;
715 
716  /**
717  * Calculates the area of a triangle.
718  *
719  * \param triIdx The id of the triangle to calculate the area of.
720  *
721  * \return The area of the triangle.
722  */
723  float calcTriangleArea( std::size_t triIdx ) const;
724 
725  /**
726  * Calculates the angle between two NORMALIZED vectors. Asserts in debug mode, in release mode
727  * when called with non-normalized vectors, results are undefined.
728  *
729  * \param v1 The first NORMALIZED vector.
730  * \param v2 The second NORMALIZED vector.
731  *
732  * \return The angle between the vectors in radians.
733  */
734  double calcAngleBetweenNormalizedVectors( osg::Vec3 const& v1, osg::Vec3 const& v2 );
735 
736  size_t m_countVerts; //!< number of vertexes in the mesh
737 
738  size_t m_countTriangles; //!< number of triangles in the mesh
739 
740  bool m_meshDirty; //!< flag indicating a change took place which requires a recalculation of components
741 
742  bool m_autoNormal; //!< flag denoting whether normals should be calculated automatically.
743 
744  bool m_neighborsCalculated; //!< flag indicating whether the neighbor information has been calculated yet
745 
746  //! Indicates whether the curvature and its principal directions have been calculated.
748 
749  osg::ref_ptr< osg::Vec3Array > m_verts; //!< array containing the vertices
750 
751  osg::ref_ptr< osg::Vec3Array > m_textureCoordinates; //!< array containing the texture coordinates
752 
753  osg::ref_ptr< osg::Vec3Array > m_vertNormals; //!< array containing the vertex normals
754 
755  osg::ref_ptr< osg::Vec4Array > m_vertColors; //!< array containing vertex colors
756 
757  std::vector< size_t > m_triangles; //!< array containing the triangles
758 
759  osg::ref_ptr< osg::Vec3Array > m_triangleNormals; //!< array containing the triangle normals
760 
761  osg::ref_ptr< osg::Vec4Array > m_triangleColors; //!< array containing the triangle colors
762 
763  // helper structures
764  std::vector < std::vector< size_t > > m_vertexIsInTriangle; //!< for each vertex, list of triangles it is part of
765 
766  std::vector< std::vector< size_t > > m_triangleNeighbors; //!< edge neighbors for each triangle
767 
768  //! Stores the maximum normal curvature (for the first principal direction) for each vertex.
769  boost::shared_ptr< std::vector< float > > m_mainNormalCurvature;
770 
771  //! Stores the minimum normal curvature (for the second principal direction) for each vertex.
772  boost::shared_ptr< std::vector< float > > m_secondaryNormalCurvature;
773 
774  //! Stores the first principal curvature direction for each vertex.
775  osg::ref_ptr< osg::Vec3Array > m_mainCurvaturePrincipalDirection;
776 
777  //! Stores the second principal curvature direction for each vertex.
778  osg::ref_ptr< osg::Vec3Array > m_secondaryCurvaturePrincipalDirection;
779 
780  size_t m_numTriVerts; //!< stores the number of vertexes before the loop subdivion is run, needed by the loop algorithm
781 
782  size_t m_numTriFaces; //!< stores the number of triangles before the loop subdivion is run, needed by the loop algorithm
783 };
784 
785 /**
786  * TriangleMesh utils
787  */
788 namespace tm_utils
789 {
790  /**
791  * Decompose the given mesh into connected components.
792  *
793  * \param mesh The triangle mesh to decompose
794  *
795  * \return List of components where each of them is a WTriangleMesh again.
796  */
797  boost::shared_ptr< std::list< boost::shared_ptr< WTriangleMesh > > > componentDecomposition( const WTriangleMesh& mesh );
798 
799  /**
800  * Prints for each mesh \#vertices and \#triangles, as well as each triangle with its positions. No point IDs are printed.
801  *
802  * \param os Output stream to print on.
803  * \param rhs The mesh instance.
804  *
805  * \return The output stream again for further usage.
806  */
807  std::ostream& operator<<( std::ostream& os, const WTriangleMesh& rhs );
808 }
809 
810 inline bool WTriangleMesh::operator==( const WTriangleMesh& rhs ) const
811 {
812  return std::equal( m_verts->begin(), m_verts->end(), rhs.m_verts->begin() ) &&
813  std::equal( m_triangles.begin(), m_triangles.end(), rhs.m_triangles.begin() );
814 }
815 
816 inline void WTriangleMesh::addTextureCoordinate( osg::Vec3 texCoord )
817 {
818  ( *m_textureCoordinates )[m_countVerts-1] = texCoord;
819 }
820 
821 inline void WTriangleMesh::addTextureCoordinate( float x, float y, float z )
822 {
823  addTextureCoordinate( osg::Vec3( x, y, z ) );
824 }
825 
826 inline size_t WTriangleMesh::addVertex( osg::Vec3 vert )
827 {
828  if( ( *m_verts ).size() == m_countVerts )
829  {
830  ( *m_verts ).resize( m_countVerts + 1 );
831  }
832  if( ( *m_textureCoordinates ).size() == m_countVerts )
833  {
834  ( *m_textureCoordinates ).resize( m_countVerts + 1 );
835  }
836  if( ( *m_vertColors ).size() == m_countVerts )
837  {
838  ( *m_vertColors ).resize( m_countVerts + 1 );
839  ( *m_vertColors )[ m_countVerts ] = osg::Vec4( 1.0, 1.0, 1.0, 1.0 );
840  }
841  if( ( *m_vertNormals ).size() == m_countVerts )
842  {
843  ( *m_vertNormals ).resize( m_countVerts + 1 );
844  }
845 
846  size_t index = m_countVerts;
847  ( *m_verts )[index] = vert;
848  ( *m_vertNormals )[index] = osg::Vec3( 1.0, 1.0, 1.0 );
849 
850  ++m_countVerts;
851  return index;
852 }
853 
854 inline const std::string WTriangleMesh::getName() const
855 {
856  return "WTriangleMesh";
857 }
858 
859 inline const std::string WTriangleMesh::getDescription() const
860 {
861  return "Triangle mesh data structure allowing for convenient access of the elements.";
862 }
863 
864 inline void WTriangleMesh::setTriVert0( size_t triId, size_t vertId )
865 {
866  WAssert( triId < m_countTriangles, "set tri vert 0: triangle id out of range" );
867  WAssert( vertId < m_countVerts, "vertex id out of range" );
868  m_triangles[ triId * 3 ] = vertId;
869 }
870 
871 inline void WTriangleMesh::setTriVert1( size_t triId, size_t vertId )
872 {
873  WAssert( triId < m_countTriangles, "set tri vert 1: triangle id out of range" );
874  WAssert( vertId < m_countVerts, "vertex id out of range" );
875  m_triangles[ triId * 3 + 1] = vertId;
876 }
877 
878 inline void WTriangleMesh::setTriVert2( size_t triId, size_t vertId )
879 {
880  WAssert( triId < m_countTriangles, "set tri vert 2: triangle id out of range" );
881  WAssert( vertId < m_countVerts, "vertex id out of range" );
882  m_triangles[ triId * 3 + 2] = vertId;
883 }
884 
885 inline osg::Vec3 WTriangleMesh::getTriVert( size_t triId, size_t vertNum )
886 {
887  WAssert( triId < m_countTriangles, "triangle id out of range" );
888  return ( *m_verts )[ m_triangles[ triId * 3 + vertNum] ];
889 }
890 
891 inline size_t WTriangleMesh::getTriVertId0( size_t triId ) const
892 {
893  WAssert( triId < m_countTriangles, "get tri vert id 0: triangle id out of range" );
894  return m_triangles[triId * 3];
895 }
896 
897 inline size_t WTriangleMesh::getTriVertId1( size_t triId ) const
898 {
899  WAssert( triId < m_countTriangles, "get tri vert id 1: triangle id out of range" );
900  return m_triangles[triId * 3 + 1];
901 }
902 
903 inline size_t WTriangleMesh::getTriVertId2( size_t triId ) const
904 {
905  WAssert( triId < m_countTriangles, "get tri vert id 2: triangle id out of range" );
906  return m_triangles[triId * 3 + 2];
907 }
908 
909 inline void WTriangleMesh::setVertex( size_t index, osg::Vec3 vert )
910 {
911  ( *m_verts )[index] = vert;
912 }
913 
914 #endif // WTRIANGLEMESH_H