22#define GLM_FORCE_RADIANS
25#include <glm/gtc/type_ptr.hpp>
30#define LOWER_LIMIT (1e-12)
40 dx =
double{ pts[1].x } - pts[0].x;
41 dy =
double{ pts[1].y } - pts[0].y;
42 dz =
double{ pts[1].z } - pts[0].z;
47 dx =
double{ pts[2].x } - pts[0].x;
48 dy =
double{ pts[2].y } - pts[0].y;
49 dz =
double{ pts[2].z } - pts[0].z;
54 dx =
double{ pts[2].x } - pts[1].x;
55 dy =
double{ pts[2].y } - pts[1].y;
56 dz =
double{ pts[2].z } - pts[1].z;
68 glm::vec3 tri = glm::vec3( 0.0, 0.0, 0.0 );
80 tri = glm::cross( pts[2] - pts[0], pts[1] - pts[0] );
82 float dn = sqrtf( tri.x * tri.x + tri.y * tri.y + tri.z * tri.z );
104 float p12 = dx*dx + dy*dy + dz*dz;
110 float p23 = dx*dx + dy*dy + dz*dz;
115 float p13 = dx*dx + dy*dy + dz*dz;
118 float dn = 2.0f * l12 * l13;
123 if( ( p12 + p13 - p23 ) < FLT_EPSILON )
126 if( ( p12 + p13 - p23 ) > FLT_EPSILON )
132 float cosAngle = ( p12 + p13 - p23 ) / dn;
135 if( cosAngle > 1.0f )
137 else if( cosAngle < -1.0f )
202 colors.push_back( aColor );
223 std::vector< WRLVEC3F >::iterator sV =
vertices.begin();
224 std::vector< WRLVEC3F >::iterator eV =
vertices.end();
240 glm::vec3 sum( 0.0, 0.0, 0.0 );
243 for(
size_t i = 1; i < nv; ++i, ++j )
247 float a2 = acosf(
VCalcCosAngle( lCPts[1], lCPts[0], lCPts[2] ) );
254 float maxV = fabs( wnorm.x );
255 float tV = fabs( wnorm.y );
260 tV = fabs( wnorm.z );
279 tV = fabs( wnorm.x );
284 tV = fabs( wnorm.y );
289 tV = fabs( wnorm.z );
306 tV = fabs( wnorm.x );
311 tV = fabs( wnorm.y );
316 tV = fabs( wnorm.z );
336 std::vector< int >::iterator sI =
indices.begin();
337 std::vector< int >::iterator eI =
indices.end();
353 std::list< FACET* >::iterator sF = aFacetList.begin();
354 std::list< FACET* >::iterator eF = aFacetList.end();
365 (*sF)->GetFaceNormal( fp[1] );
369 if( aCreaseLimit <= thrs && (*sF)->GetWeightedNormal( aIndex, fp[1] ) )
371 norms[idx].x += fp[1].x;
372 norms[idx].y += fp[1].y;
373 norms[idx].z += fp[1].z;
392 if( fabs(
norms[idx].x ) < 0.5
393 && fabs(
norms[idx].y ) < 0.5
394 && fabs(
norms[idx].z ) < 0.5 )
421 std::vector< int >::iterator sI =
indices.begin();
422 std::vector< int >::iterator eI =
indices.end();
458bool FACET::GetData( std::vector< WRLVEC3F >& aVertexList, std::vector< WRLVEC3F >& aNormalsList,
459 std::vector< SGCOLOR >& aColorsList,
WRL1_ORDER aVertexOrder )
476 aVertexList.push_back(
vertices[idx[0]] );
477 aVertexList.push_back(
vertices[idx[1]] );
478 aVertexList.push_back(
vertices[idx[2]] );
480 aNormalsList.push_back(
norms[idx[0]] );
481 aNormalsList.push_back(
norms[idx[1]] );
482 aNormalsList.push_back(
norms[idx[2]] );
487 aVertexList.push_back(
vertices[idx[0]] );
488 aVertexList.push_back(
vertices[idx[2]] );
489 aVertexList.push_back(
vertices[idx[1]] );
491 tnorm =
norms[idx[0]];
495 aNormalsList.push_back( tnorm );
497 tnorm =
norms[idx[2]];
501 aNormalsList.push_back( tnorm );
503 tnorm =
norms[idx[1]];
507 aNormalsList.push_back( tnorm );
510 bool hasColor =
false;
524 aColorsList.push_back(
colors[idx[0]] );
525 aColorsList.push_back(
colors[idx[1]] );
526 aColorsList.push_back(
colors[idx[2]] );
531 aColorsList.push_back(
colors[idx[0]] );
532 aColorsList.push_back(
colors[idx[2]] );
533 aColorsList.push_back(
colors[idx[1]] );
540 aColorsList.push_back(
colors[0] );
541 aColorsList.push_back(
colors[0] );
542 aColorsList.push_back(
colors[0] );
547 aColorsList.push_back(
colors[0] );
548 aColorsList.push_back(
colors[0] );
549 aColorsList.push_back(
colors[0] );
554 int lim = (int)
vertices.size() - 1;
556 while( idx[2] < lim )
563 aVertexList.push_back(
vertices[idx[0]] );
564 aVertexList.push_back(
vertices[idx[1]] );
565 aVertexList.push_back(
vertices[idx[2]] );
567 aNormalsList.push_back(
norms[idx[0]] );
568 aNormalsList.push_back(
norms[idx[1]] );
569 aNormalsList.push_back(
norms[idx[2]] );
574 aVertexList.push_back(
vertices[idx[0]] );
575 aVertexList.push_back(
vertices[idx[2]] );
576 aVertexList.push_back(
vertices[idx[1]] );
578 tnorm =
norms[idx[0]];
582 aNormalsList.push_back( tnorm );
584 tnorm =
norms[idx[2]];
588 aNormalsList.push_back( tnorm );
590 tnorm =
norms[idx[1]];
594 aNormalsList.push_back( tnorm );
603 aColorsList.push_back(
colors[idx[0]] );
604 aColorsList.push_back(
colors[idx[1]] );
605 aColorsList.push_back(
colors[idx[2]] );
610 aColorsList.push_back(
colors[idx[0]] );
611 aColorsList.push_back(
colors[idx[2]] );
612 aColorsList.push_back(
colors[idx[1]] );
619 aColorsList.push_back(
colors[0] );
620 aColorsList.push_back(
colors[0] );
621 aColorsList.push_back(
colors[0] );
626 aColorsList.push_back(
colors[0] );
627 aColorsList.push_back(
colors[0] );
628 aColorsList.push_back(
colors[0] );
645 if( (
maxIdx + 1) >= (
int)aFacetList.size() )
646 aFacetList.resize(
static_cast<std::size_t
>(
maxIdx ) + 1 );
648 std::vector< int >::iterator sI =
indices.begin();
649 std::vector< int >::iterator eI =
indices.end();
653 aFacetList[*sI].push_back(
this );
666 for(
size_t i = 0; i < vs; ++i )
677 std::list< FACET* >::iterator sF =
facets.begin();
678 std::list< FACET* >::iterator eF =
facets.end();
700 float aCreaseLimit,
bool isVRML2 )
705 std::vector< std::list< FACET* > > flist;
708 std::list< FACET* >::iterator sF =
facets.begin();
709 std::list< FACET* >::iterator eF =
facets.end();
718 tV = ( *sF )->CalcFaceNormal();
719 tmi = ( *sF )->GetMaxIndex();
735 flist.resize( maxIdx );
742 ( *sF )->Renormalize( tV );
743 ( *sF )->CollectVertices( flist );
748 size_t vs = flist.size();
750 for(
size_t i = 0; i < vs; ++i )
752 sF = flist[i].begin();
757 ( *sF )->CalcVertexNormal(
static_cast<int>( i ), flist[i], aCreaseLimit );
762 std::vector< WRLVEC3F > vertices;
763 std::vector< WRLVEC3F > normals;
764 std::vector< SGCOLOR > colors;
772 ( *sF )->GetData( vertices, normals, colors, aVertexOrder );
778 if( vertices.size() < 3 )
796 std::vector< SGPOINT > lCPts;
797 std::vector< SGVECTOR > lCNorm;
798 vs = vertices.size();
800 for(
size_t i = 0; i < vs; ++i )
803 pt.
x = vertices[i].x;
804 pt.
y = vertices[i].y;
805 pt.
z = vertices[i].z;
806 lCPts.push_back( pt );
807 lCNorm.emplace_back( normals[i].x, normals[i].y, normals[i].z );
824 for(
int i = 0; i < (int)lCPts.size(); ++i )
830 if( !colors.empty() )
std::vector< SGCOLOR > colors
std::vector< WRLVEC3F > vnweight
bool GetFaceNormal(WRLVEC3F &aNorm)
Retrieve the normal for this facet.
void Renormalize(float aMaxValue)
std::vector< WRLVEC3F > vertices
bool GetWeightedNormal(int aIndex, WRLVEC3F &aNorm)
Retrieve the angle weighted normal for the given vertex index.
float CalcFaceNormal()
Calculate the normal to the facet assuming a CCW orientation and perform the calculation of the angle...
void CollectVertices(std::vector< std::list< FACET * > > &aFacetList)
Add a pointer to this object at each position within aFacetList referenced by the internal vertex ind...
void AddVertex(WRLVEC3F &aVertex, int aIndex)
Add the vertex and its associated index to the internal list of polygon vertices.
std::vector< WRLVEC3F > norms
std::vector< int > indices
void CalcVertexNormal(int aIndex, std::list< FACET * > &aFacetList, float aCreaseAngle)
Calculate the weighted normal for the given vertex.
void AddColor(const SGCOLOR &aColor)
Add the given RGB color to the internal list.
bool GetData(std::vector< WRLVEC3F > &aVertexList, std::vector< WRLVEC3F > &aNormalsList, std::vector< SGCOLOR > &aColorsList, WRL1_ORDER aVertexOrder)
Package the internal data as triangles with corresponding per-vertex normals.
The wrapper for SGCOLORS.
bool SetColorList(size_t aListSize, const SGCOLOR *aColorList)
The wrapper for SGCOORDINDEX.
The wrapper for SGCOORDS.
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
The wrapper for the SGFACESET class.
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
bool AddIndex(int aIndex)
Add a single index to the list.
SGNODE * GetRawPtr(void) noexcept
Return the raw internal SGNODE pointer.
bool AddChildNode(SGNODE *aNode)
Add a node as a child owned by this node.
bool AddRefNode(SGNODE *aNode)
Add a reference to an existing node which is not owned by (not a child of) this node.
The wrapper for the SGNORMALS class.
bool SetNormalList(size_t aListSize, const SGVECTOR *aNormalList)
The wrapper for the SGSHAPE class.
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
The base class of all Scene Graph nodes.
SGNODE * CalcShape(SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
std::list< FACET * > facets
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
static bool VDegenerate(glm::vec3 *pts)
static float VCalcCosAngle(const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
static WRLVEC3F VCalcTriNorm(const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
declares classes to help manage normals calculations from VRML files