37 #include <Eigen/Eigenvalues>
38 #include <osg/io_utils>
40 #include "../common/WAssert.h"
41 #include "../common/WLogger.h"
42 #include "../common/datastructures/WUnionFind.h"
43 #include "../common/math/WMath.h"
44 #include "WTriangleMesh.h"
63 m_countTriangles( 0 ),
66 m_neighborsCalculated( false ),
67 m_curvatureCalculated( false )
69 m_verts = osg::ref_ptr< osg::Vec3Array >(
new osg::Vec3Array( vertNum ) );
71 m_vertNormals = osg::ref_ptr< osg::Vec3Array >(
new osg::Vec3Array( vertNum ) );
72 m_vertFlatNormals = osg::ref_ptr< osg::Vec3Array >(
new osg::Vec3Array( vertNum ) );
73 m_vertColors = osg::ref_ptr< osg::Vec4Array >(
new osg::Vec4Array( vertNum ) );
76 m_triangleNormals = osg::ref_ptr< osg::Vec3Array >(
new osg::Vec3Array( triangleNum ) );
77 m_triangleColors = osg::ref_ptr< osg::Vec4Array >(
new osg::Vec4Array( triangleNum ) );
81 : m_countVerts( vertices->size() ),
82 m_countTriangles( triangles.size() / 3 ),
85 m_neighborsCalculated( false ),
87 m_textureCoordinates( new osg::Vec3Array( vertices->size() ) ),
88 m_vertNormals( new osg::Vec3Array( vertices->size() ) ),
89 m_vertFlatNormals( new osg::Vec3Array( vertices->size() ) ),
90 m_vertColors( new osg::Vec4Array( vertices->size() ) ),
91 m_triangles( triangles ),
92 m_triangleNormals( new osg::Vec3Array( triangles.size() / 3 ) ),
93 m_triangleColors( new osg::Vec4Array( triangles.size() / 3 ) )
95 WAssert( triangles.size() % 3 == 0,
"Invalid triangle vector, having an invalid size (not divideable by 3)" );
109 return addVertex( osg::Vec3( x, y, z ) );
114 return addVertex( osg::Vec3( vert[0], vert[1], vert[2] ) );
139 WAssert( index <
m_countVerts,
"set vertex normal: index out of range" );
140 ( *m_vertNormals )[index] = normal;
145 setVertexNormal( index, osg::Vec3( normal[0], normal[1], normal[2] ) );
155 WAssert( index <
m_countVerts,
"set vertex color: index out of range" );
156 ( *m_vertColors )[index] = color;
161 WAssert( index <
m_countTriangles,
"set triangle color: index out of range" );
162 ( *m_triangleColors )[index] = color;
225 WAssert( index <
m_countVerts,
"get vertex: index out of range" );
231 WAssert( index <
m_countVerts,
"get vertex color: index out of range" );
237 WAssert( index <
m_countVerts,
"get normal as position: index out of range" );
247 WAssert( index <
m_countVerts,
"remove vertex: index out of range" );
252 ( *m_verts ).erase( ( *m_verts ).begin() + index );
284 for(
size_t vertId = 0; vertId <
m_countVerts; ++vertId )
286 osg::Vec3 tempNormal( 0.0, 0.0, 0.0 );
287 osg::Vec3 tempFlatNormal( 0.0, 0.0, 0.0 );
295 tempNormal.normalize();
296 ( *m_vertNormals )[vertId] = tempNormal;
297 ( *m_vertFlatNormals )[vertId] = tempFlatNormal;
306 std::vector< size_t >v;
322 osg::Vec3 tempNormal( 0, 0, 0 );
324 tempNormal[0] = v1[1] * v2[2] - v1[2] * v2[1];
325 tempNormal[1] = v1[2] * v2[0] - v1[0] * v2[2];
326 tempNormal[2] = v1[0] * v2[1] - v1[1] * v2[0];
328 tempNormal.normalize();
335 osg::Vec3 v1( vert1 - vert0 );
336 osg::Vec3 v2( vert2 - vert0 );
338 osg::Vec3 tempNormal( 0, 0, 0 );
340 tempNormal[0] = v1[1] * v2[2] - v1[2] * v2[1];
341 tempNormal[1] = v1[2] * v2[0] - v1[0] * v2[2];
342 tempNormal[2] = v1[0] * v2[1] - v1[1] * v2[0];
344 tempNormal.normalize();
361 std::vector<size_t> v( 3, -1 );
382 for(
size_t i = 0; i < candidates.size(); ++i )
384 for(
size_t k = 0; k < compares.size(); ++k )
386 if( ( candidates[i] != triangleNum ) && ( candidates[i] == compares[k] ) )
388 return candidates[i];
405 osg::Vec3* newVertexPositions =
new osg::Vec3[
m_numTriVerts];
419 std::vector< size_t >v;
431 ( *m_verts )[i] = newVertexPositions[i];
434 delete[] newVertexPositions;
447 int starSize = starP.size();
452 double scale = 1.0 - (
static_cast<double>( starSize ) * alpha );
457 for(
int i = 0; i < starSize; i++ )
460 osg::Vec3 translate =
getVertex( edgeV );
465 return oldPos + newPos;
476 addTriangle( edgeVerts[0], edgeVerts[1], edgeVerts[2] );
482 size_t neighborVert = -1;
483 size_t neighborFaceNum = -1;
486 neighborFaceNum =
getNeighbor( edgeV1, edgeV2, triId );
488 if( neighborFaceNum == triId )
490 osg::Vec3 edgeVert = ( ( *m_verts )[edgeV1] + ( *m_verts )[edgeV2] ) / 2.0;
496 else if( neighborFaceNum > triId )
500 osg::Vec3 edgePart = ( *m_verts )[edgeV1] + ( *m_verts )[edgeV2];
501 osg::Vec3 neighborPart = ( *m_verts )[neighborVert] + ( *m_verts )[V3];
503 edgeVert = ( ( edgePart * ( 3.0 / 8.0 ) ) + ( neighborPart * ( 1.0 / 8.0 ) ) );
511 size_t neighborP = neighborFaceNum;
546 addTriangle( originalTri1, centerTri1, centerTri0 );
547 addTriangle( originalTri2, centerTri2, centerTri1 );
566 std::vector< size_t > temp;
580 double center = ( 0.375 + ( 0.25 * cos( ( 2.0 * 3.14159265358979 ) /
static_cast<double>( n ) ) ) );
581 answer = ( 0.625 - ( center * center ) ) /
static_cast<double>( n );
620 ( *m_vertColors ).resize( oldVertSize + mesh->vertSize() );
621 for(
size_t i = 0; i < mesh->vertSize(); ++i )
623 osg::Vec3 v( mesh->getVertex( i ) );
630 for(
size_t i = 0; i < mesh->triangleSize(); ++i )
632 addTriangle( mesh->getTriVertId0( i ) + oldVertSize, mesh->getTriVertId1( i ) + oldVertSize, mesh->getTriVertId2( i ) + oldVertSize );
639 osg::Vec3 t( xOff, yOff, zOff );
640 for(
size_t i = 0; i < ( *m_verts ).size(); ++i )
642 ( *m_verts )[i] += t;
648 for(
size_t i = 0; i < ( *m_verts ).size(); ++i )
650 ( *m_verts )[i] *= zoom;
659 for(
size_t vertId = 0; vertId <
m_vertColors->size(); ++vertId )
663 maxR = ( *m_vertColors )[vertId][0];
667 maxG = ( *m_vertColors )[vertId][1];
671 maxB = ( *m_vertColors )[vertId][2];
674 for(
size_t vertId = 0; vertId <
m_vertColors->size(); ++vertId )
676 ( *m_vertColors )[vertId][0] /= maxR;
677 ( *m_vertColors )[vertId][1] /= maxG;
678 ( *m_vertColors )[vertId][2] /= maxB;
684 std::stringstream ss;
685 ss <<
"WTriangleMesh( #vertices=" << rhs.
vertSize() <<
" #triangles=" << rhs.
triangleSize() <<
" )" << std::endl;
686 using string_utils::operator<<;
689 const std::vector< size_t >& triangles = rhs.
getTriangles();
690 osg::ref_ptr< const osg::Vec3Array > vertices = rhs.
getVertexArray();
691 for(
size_t vID = 0 ; vID <= triangles.size() - 3; ++count )
693 std::stringstream prefix;
694 prefix <<
"triangle: " << count <<
"[ ";
695 std::string indent( prefix.str().size(),
' ' );
696 using osg::operator<<;
697 ss << prefix.str() << vertices->at( triangles[ vID++ ] ) << std::endl;
698 ss << indent << vertices->at( triangles[ vID++ ] ) << std::endl;
699 ss << indent << vertices->at( triangles[ vID++ ] ) << std::endl;
700 ss << std::string( indent.size() - 2,
' ' ) <<
"]" << std::endl;
702 return os << ss.str();
707 std::shared_ptr< std::list< std::shared_ptr< WTriangleMesh > > > result(
new std::list< std::shared_ptr< WTriangleMesh > >() );
717 WAssert(
false,
"Not implemented the decomposition of a TriangleMesh without any triangles" );
727 const std::vector< size_t >& triangles = mesh.
getTriangles();
728 for(
size_t vID = 0; vID <= triangles.size() - 3; vID += 3 )
730 uf.
merge( triangles[ vID ], triangles[ vID + 1 ] );
731 uf.
merge( triangles[ vID ], triangles[ vID + 2 ] );
739 typedef std::map< osg::Vec3, size_t > VertexType;
740 typedef std::vector< size_t > TriangleType;
741 typedef std::pair< VertexType, TriangleType > BucketType;
742 std::map< size_t, BucketType > buckets;
744 osg::ref_ptr< const osg::Vec3Array > vertices = mesh.
getVertexArray();
745 for(
size_t vID = 0; vID <= triangles.size() - 3; vID += 3 )
747 size_t component = uf.
find( triangles[ vID ] );
748 if( buckets.find( component ) == buckets.end() )
750 buckets[ component ] = BucketType( VertexType(), TriangleType() );
754 VertexType& mapRef = buckets[ component ].first;
755 for(
int i = 0; i < 3; ++i )
758 const osg::Vec3& vertex = ( *vertices )[ triangles[ vID + i ] ];
759 if( mapRef.find( vertex ) == mapRef.end() )
762 mapRef[ vertex ] = id;
766 id = mapRef[ vertex ];
768 buckets[ component ].second.push_back(
id );
772 for( std::map< size_t, BucketType >::const_iterator cit = buckets.begin(); cit != buckets.end(); ++cit )
774 osg::ref_ptr< osg::Vec3Array > newVertices(
new osg::Vec3Array );
775 newVertices->resize( cit->second.first.size() );
776 for( VertexType::const_iterator vit = cit->second.first.begin(); vit != cit->second.first.end(); ++vit )
778 newVertices->at( vit->second ) = vit->first;
780 std::shared_ptr< WTriangleMesh > newMesh(
new WTriangleMesh( newVertices, cit->second.second ) );
781 result->push_back( newMesh );
809 osg::ref_ptr< osg::Vec3Array > vtxArray =
new osg::Vec3Array(
m_verts->size() );
811 for( std::size_t k = 0; k <
m_verts->size(); ++k )
817 for( std::size_t k = 0; k <
m_triangles.size() / 3; ++k )
819 osg::Vec3
const& p0 = vtxArray->operator[](
m_triangles[ 3 * k + 0 ] );
820 osg::Vec3
const& p1 = vtxArray->operator[](
m_triangles[ 3 * k + 1 ] );
821 osg::Vec3
const& p2 = vtxArray->operator[](
m_triangles[ 3 * k + 2 ] );
830 for( std::size_t k = 0; k <
m_verts->size(); ++k )
840 std::stack< std::size_t > triStack;
841 std::set< std::size_t > triSet;
849 while( !triStack.empty() )
851 std::size_t currentTriangle = triStack.top();
858 if( (
m_verts->operator[] ( vtx ) - center ).length() > 4.0 * sigmaDistance )
872 osg::Vec3 res( 0.0, 0.0, 0.0 );
874 for( std::set< std::size_t >::const_iterator it = triSet.begin(); it != triSet.end(); ++it )
880 double dist = (
m_verts->operator[] ( vtx ) - center ).length();
881 double f = 1.0 / ( sigmaDistance * sqrt( 2.0 * pi() ) ) * exp( -0.5 * dist * dist );
887 osg::Vec3f
const& p =
m_verts->operator[] ( vtx );
889 osg::Vec3f pred = p + n * ( n * ( center - p ) );
891 dist = ( p - pred ).length();
893 g = 1.0 / ( sigmaInfluence * sqrt( 2.0 * pi() ) ) * exp( -0.5 * dist * dist );
896 res += center * area * f * g;
919 return ( ( p1 - p0 ) ^ ( p2 - p0 ) ).length() * 0.5;
927 std::vector< osg::Vec3 > normals(
m_verts->size() );
936 for( std::size_t vtxId = 0; vtxId <
m_verts->size(); ++vtxId )
938 osg::Vec3
const& p =
m_verts->operator[] ( vtxId );
939 osg::Vec3 n( 0.0, 0.0, 0.0 );
946 double w = 1.0 / ( center - p ).length();
951 WAssert( n.length() > 0.0001,
"Invalid normal!" );
954 normals[ vtxId ] = n;
958 for( std::size_t vtxId = 0; vtxId <
m_verts->size(); ++vtxId )
960 osg::Vec3
const& p =
m_verts->operator[] ( vtxId );
962 osg::Vec3
const& normal = normals[ vtxId ];
965 std::set< std::size_t > neighbors;
971 for( std::size_t j = 0; j < 3; ++j )
975 if( neighbors.find( e ) == neighbors.end() && e != vtxId )
977 neighbors.insert( e );
982 WAssert( neighbors.size() > 2,
"Vertex has too few neighbors! Does this mesh have holes?" );
984 double maxCurvature = -std::numeric_limits< double >::infinity();
985 std::vector< double > curvatures;
987 osg::Vec3 maxCurvatureTangent( 0.0, 0.0, 0.0 );
988 std::vector< osg::Vec3 > tangents;
991 for( std::set< std::size_t >::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it )
993 osg::Vec3
const& neighbPos =
m_verts->operator[] ( *it );
994 osg::Vec3
const& neighbNormal = normals[ *it ];
997 osg::Vec3 tangent = ( neighbPos - p ) - normal * ( ( neighbPos - p ) * normal );
1001 double ncurv = -1.0 * ( ( neighbPos - p ) * ( neighbNormal - normal ) ) / ( ( neighbPos - p ) * ( neighbPos - p ) );
1003 if( ncurv > maxCurvature )
1005 maxCurvature = ncurv;
1006 maxCurvatureTangent = tangent;
1009 tangents.push_back( tangent );
1010 curvatures.push_back( ncurv );
1013 WAssert( maxCurvatureTangent.length() > 0.0001,
"Invalid tangent length!" );
1016 osg::Vec3
const& e1 = maxCurvatureTangent;
1017 osg::Vec3 e2 = e1 ^ normal;
1021 bool significantCurvature =
false;
1022 for( std::vector< double >::const_iterator it = curvatures.begin(); it != curvatures.end(); ++it )
1024 if( fabs( *it ) > 0.00001 )
1026 significantCurvature =
true;
1031 if( !significantCurvature )
1046 double const& a = maxCurvature;
1048 Eigen::Matrix< double, -1, -1 > X( tangents.size(), 2 );
1049 Eigen::Matrix< double, -1, -1 > y( tangents.size(), 1 );
1051 for( std::size_t k = 0; k < tangents.size(); ++k )
1055 X( k, 0 ) = cos( theta ) * sin( theta );
1056 X( k, 1 ) = sin( theta ) * sin( theta );
1057 y( k, 0 ) = curvatures[ k ] - a * cos( theta ) * cos( theta );
1061 Eigen::FullPivLU< Eigen::Matrix< double, -1, -1 > > lu( X );
1066 wlog::warn(
"WTriangleMesh::estimateCurvature" ) <<
"Rank too low, cannot estimate curvature for this vertex!";
1077 Eigen::Matrix< double, -1, -1 > bb = ( X.transpose() * X ).inverse() * X.transpose() * y;
1080 double b = bb( 0, 0 );
1081 double c = bb( 1, 0 );
1085 double Kg = a * c - 0.25 * b * b;
1086 double H = 0.5 * ( a + c );
1087 double s = H * H - Kg;
1094 double k1 = H + sqrt( s );
1095 double k2 = H - sqrt( s );
1097 if( fabs( k1 - k2 ) < 0.000001 )
1106 double temp = b / ( k2 - k1 );
1117 double theta = 0.5 * asin( temp );
1119 osg::Vec3 ne1 = e1 * cos( theta ) + e2 * sin( theta );
1120 osg::Vec3 ne2 = e2 * cos( theta ) - e1 * sin( theta );
1130 + b * cos( theta ) * sin( theta )
1131 + c * sin( theta ) * sin( theta );
1138 + b * cos( theta ) * sin( theta )
1139 + c * sin( theta ) * sin( theta );
1149 WAssert( v1.length() < 1.0001,
"Vector is not normalized!" );
1150 WAssert( v1.length() > -1.0001,
"Vector is not normalized!" );
1151 WAssert( v2.length() < 1.0001,
"Vector is not normalized!" );
1152 WAssert( v2.length() > -1.0001,
"Vector is not normalized!" );
1154 double temp = v1 * v2;
1166 return acos( temp );
This only is a 3d double vector.
Triangle mesh data structure allowing for convenient access of the elements.
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.
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
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
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.
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
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.
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
Implements a very simple union-find datastructure aka disjoint_sets.
void merge(size_t i, size_t j)
Merges two components (iow: makes a union) where the given elements are members of.
size_t find(size_t x)
Find the canonical element of the given element and do path compression.
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.
WStreamedLogger warn(const std::string &source)
Logging a warning message.