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