26#define GLM_FORCE_RADIANS
29#include <glm/gtc/type_ptr.hpp>
34#define LOWER_LIMIT (1e-12)
44 dx =
double{ pts[1].x } - pts[0].x;
45 dy =
double{ pts[1].y } - pts[0].y;
46 dz =
double{ pts[1].z } - pts[0].z;
51 dx =
double{ pts[2].x } - pts[0].x;
52 dy =
double{ pts[2].y } - pts[0].y;
53 dz =
double{ pts[2].z } - pts[0].z;
58 dx =
double{ pts[2].x } - pts[1].x;
59 dy =
double{ pts[2].y } - pts[1].y;
60 dz =
double{ pts[2].z } - pts[1].z;
72 glm::vec3 tri = glm::vec3( 0.0, 0.0, 0.0 );
84 tri = glm::cross( pts[2] - pts[0], pts[1] - pts[0] );
86 float dn = sqrtf( tri.x * tri.x + tri.y * tri.y + tri.z * tri.z );
108 float p12 = dx*dx + dy*dy + dz*dz;
114 float p23 = dx*dx + dy*dy + dz*dz;
119 float p13 = dx*dx + dy*dy + dz*dz;
122 float dn = 2.0f * l12 * l13;
127 if( ( p12 + p13 - p23 ) < FLT_EPSILON )
130 if( ( p12 + p13 - p23 ) > FLT_EPSILON )
136 float cosAngle = ( p12 + p13 - p23 ) / dn;
139 if( cosAngle > 1.0f )
141 else if( cosAngle < -1.0f )
206 colors.push_back( aColor );
227 std::vector< WRLVEC3F >::iterator sV =
vertices.begin();
228 std::vector< WRLVEC3F >::iterator eV =
vertices.end();
244 glm::vec3 sum( 0.0, 0.0, 0.0 );
247 for(
size_t i = 1; i < nv; ++i, ++j )
251 float a2 = acosf(
VCalcCosAngle( lCPts[1], lCPts[0], lCPts[2] ) );
258 float maxV = fabs( wnorm.x );
259 float tV = fabs( wnorm.y );
264 tV = fabs( wnorm.z );
283 tV = fabs( wnorm.x );
288 tV = fabs( wnorm.y );
293 tV = fabs( wnorm.z );
310 tV = fabs( wnorm.x );
315 tV = fabs( wnorm.y );
320 tV = fabs( wnorm.z );
340 std::vector< int >::iterator sI =
indices.begin();
341 std::vector< int >::iterator eI =
indices.end();
357 std::list< FACET* >::iterator sF = aFacetList.begin();
358 std::list< FACET* >::iterator eF = aFacetList.end();
369 (*sF)->GetFaceNormal( fp[1] );
373 if( aCreaseLimit <= thrs && (*sF)->GetWeightedNormal( aIndex, fp[1] ) )
375 norms[idx].x += fp[1].x;
376 norms[idx].y += fp[1].y;
377 norms[idx].z += fp[1].z;
396 if( fabs(
norms[idx].x ) < 0.5
397 && fabs(
norms[idx].y ) < 0.5
398 && fabs(
norms[idx].z ) < 0.5 )
425 std::vector< int >::iterator sI =
indices.begin();
426 std::vector< int >::iterator eI =
indices.end();
462bool FACET::GetData( std::vector< WRLVEC3F >& aVertexList, std::vector< WRLVEC3F >& aNormalsList,
463 std::vector< SGCOLOR >& aColorsList,
WRL1_ORDER aVertexOrder )
478 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
480 aVertexList.push_back(
vertices[idx[0]] );
481 aVertexList.push_back(
vertices[idx[1]] );
482 aVertexList.push_back(
vertices[idx[2]] );
484 aNormalsList.push_back(
norms[idx[0]] );
485 aNormalsList.push_back(
norms[idx[1]] );
486 aNormalsList.push_back(
norms[idx[2]] );
489 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
491 aVertexList.push_back(
vertices[idx[0]] );
492 aVertexList.push_back(
vertices[idx[2]] );
493 aVertexList.push_back(
vertices[idx[1]] );
495 tnorm =
norms[idx[0]];
499 aNormalsList.push_back( tnorm );
501 tnorm =
norms[idx[2]];
505 aNormalsList.push_back( tnorm );
507 tnorm =
norms[idx[1]];
511 aNormalsList.push_back( tnorm );
514 bool hasColor =
false;
526 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
528 aColorsList.push_back(
colors[idx[0]] );
529 aColorsList.push_back(
colors[idx[1]] );
530 aColorsList.push_back(
colors[idx[2]] );
533 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
535 aColorsList.push_back(
colors[idx[0]] );
536 aColorsList.push_back(
colors[idx[2]] );
537 aColorsList.push_back(
colors[idx[1]] );
542 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
544 aColorsList.push_back(
colors[0] );
545 aColorsList.push_back(
colors[0] );
546 aColorsList.push_back(
colors[0] );
549 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
551 aColorsList.push_back(
colors[0] );
552 aColorsList.push_back(
colors[0] );
553 aColorsList.push_back(
colors[0] );
558 int lim = (int)
vertices.size() - 1;
560 while( idx[2] < lim )
565 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
567 aVertexList.push_back(
vertices[idx[0]] );
568 aVertexList.push_back(
vertices[idx[1]] );
569 aVertexList.push_back(
vertices[idx[2]] );
571 aNormalsList.push_back(
norms[idx[0]] );
572 aNormalsList.push_back(
norms[idx[1]] );
573 aNormalsList.push_back(
norms[idx[2]] );
576 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
578 aVertexList.push_back(
vertices[idx[0]] );
579 aVertexList.push_back(
vertices[idx[2]] );
580 aVertexList.push_back(
vertices[idx[1]] );
582 tnorm =
norms[idx[0]];
586 aNormalsList.push_back( tnorm );
588 tnorm =
norms[idx[2]];
592 aNormalsList.push_back( tnorm );
594 tnorm =
norms[idx[1]];
598 aNormalsList.push_back( tnorm );
605 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
607 aColorsList.push_back(
colors[idx[0]] );
608 aColorsList.push_back(
colors[idx[1]] );
609 aColorsList.push_back(
colors[idx[2]] );
612 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
614 aColorsList.push_back(
colors[idx[0]] );
615 aColorsList.push_back(
colors[idx[2]] );
616 aColorsList.push_back(
colors[idx[1]] );
621 if( aVertexOrder != WRL1_ORDER::ORD_CLOCKWISE )
623 aColorsList.push_back(
colors[0] );
624 aColorsList.push_back(
colors[0] );
625 aColorsList.push_back(
colors[0] );
628 if( aVertexOrder != WRL1_ORDER::ORD_CCW )
630 aColorsList.push_back(
colors[0] );
631 aColorsList.push_back(
colors[0] );
632 aColorsList.push_back(
colors[0] );
649 if( (
maxIdx + 1) >= (
int)aFacetList.size() )
650 aFacetList.resize(
static_cast<std::size_t
>(
maxIdx ) + 1 );
652 std::vector< int >::iterator sI =
indices.begin();
653 std::vector< int >::iterator eI =
indices.end();
657 aFacetList[*sI].push_back(
this );
670 for(
size_t i = 0; i < vs; ++i )
681 std::list< FACET* >::iterator sF =
facets.begin();
682 std::list< FACET* >::iterator eF =
facets.end();
704 float aCreaseLimit,
bool isVRML2 )
709 std::vector< std::list< FACET* > > flist;
712 std::list< FACET* >::iterator sF =
facets.begin();
713 std::list< FACET* >::iterator eF =
facets.end();
722 tV = ( *sF )->CalcFaceNormal();
723 tmi = ( *sF )->GetMaxIndex();
739 flist.resize( maxIdx );
746 ( *sF )->Renormalize( tV );
747 ( *sF )->CollectVertices( flist );
752 size_t vs = flist.size();
754 for(
size_t i = 0; i < vs; ++i )
756 sF = flist[i].begin();
761 ( *sF )->CalcVertexNormal(
static_cast<int>( i ), flist[i], aCreaseLimit );
766 std::vector< WRLVEC3F > vertices;
767 std::vector< WRLVEC3F > normals;
768 std::vector< SGCOLOR > colors;
776 ( *sF )->GetData( vertices, normals, colors, aVertexOrder );
782 if( vertices.size() < 3 )
800 std::vector< SGPOINT > lCPts;
801 std::vector< SGVECTOR > lCNorm;
802 vs = vertices.size();
804 for(
size_t i = 0; i < vs; ++i )
807 pt.
x = vertices[i].x;
808 pt.
y = vertices[i].y;
809 pt.
z = vertices[i].z;
810 lCPts.push_back( pt );
811 lCNorm.emplace_back( normals[i].x, normals[i].y, normals[i].z );
828 for(
int i = 0; i < (int)lCPts.size(); ++i )
834 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.
IFSG_COLORS is the wrapper for SGCOLORS.
bool SetColorList(size_t aListSize, const SGCOLOR *aColorList)
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COORDS is the wrapper for SGCOORDS.
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
IFSG_FACESET is the wrapper for the SGFACESET class.
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.
bool AddIndex(int aIndex)
Function AddIndex adds a single index to the list.
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
bool AddChildNode(SGNODE *aNode)
Function AddChildNode adds a node as a child owned by this node.
bool AddRefNode(SGNODE *aNode)
Function AddRefNode adds a reference to an existing node which is not owned by (not a child of) this ...
IFSG_NORMALS is the wrapper for the SGNORMALS class.
bool SetNormalList(size_t aListSize, const SGVECTOR *aNormalList)
IFSG_SHAPE is the wrapper for the SGSHAPE class.
bool NewNode(SGNODE *aParent) override
Function NewNode creates 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