Forced smoothed normals calculations for VMRML2 parser

This commit is contained in:
Cirilo Bernardo 2016-02-02 16:50:46 +11:00
parent ca9ada70a2
commit b987445676
30 changed files with 163 additions and 332 deletions

View File

@ -360,7 +360,7 @@ bool WRL2APPEARANCE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent )
{ {
if( NULL == material && NULL == texture ) if( NULL == material && NULL == texture )
return NULL; return NULL;
@ -418,7 +418,7 @@ SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals )
return m_sgNode; return m_sgNode;
} }
m_sgNode = material->TranslateToSG( aParent, calcNormals ); m_sgNode = material->TranslateToSG( aParent );
return m_sgNode; return m_sgNode;
} }

View File

@ -68,7 +68,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_APPEARANCE_H #endif // VRML2_APPEARANCE_H

View File

@ -910,7 +910,7 @@ bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
} }
SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent )
{ {
if( m_Children.empty() ) if( m_Children.empty() )
return NULL; return NULL;
@ -967,7 +967,7 @@ SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals )
do do
{ {
IFSG_TRANSFORM wrapper( topNode.GetRawPtr() ); IFSG_TRANSFORM wrapper( topNode.GetRawPtr() );
SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr(), calcNormals ); SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr() );
if( NULL != pshape ) if( NULL != pshape )
test = true; test = true;
@ -981,7 +981,7 @@ SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals )
case WRL2_TRANSFORM: case WRL2_TRANSFORM:
case WRL2_SWITCH: case WRL2_SWITCH:
if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr(), calcNormals ) ) if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr() ) )
test = true; test = true;
break; break;

View File

@ -111,7 +111,7 @@ public:
// functions inherited from WRL2NODE // functions inherited from WRL2NODE
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool SetParent( WRL2NODE* aParent ); bool SetParent( WRL2NODE* aParent );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_BASE_H #endif // VRML2_BASE_H

View File

@ -210,7 +210,7 @@ bool WRL2BOX::AddChildNode( WRL2NODE* aNode )
} }
SGNODE* WRL2BOX::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2BOX::TranslateToSG( SGNODE* aParent )
{ {
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );

View File

@ -56,7 +56,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_BOX_H #endif // VRML2_BOX_H

View File

@ -192,7 +192,7 @@ bool WRL2COLOR::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2COLOR::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2COLOR::TranslateToSG( SGNODE* aParent )
{ {
// any data manipulation must be performed by the parent node // any data manipulation must be performed by the parent node
return NULL; return NULL;

View File

@ -58,7 +58,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
/** /**
* Function HasColors * Function HasColors

View File

@ -220,7 +220,7 @@ void WRL2COORDS::GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize )
} }
SGNODE* WRL2COORDS::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2COORDS::TranslateToSG( SGNODE* aParent )
{ {
// any data manipulation must be performed by the parent node // any data manipulation must be performed by the parent node
return NULL; return NULL;

View File

@ -58,7 +58,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
void GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ); void GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize );
}; };

View File

@ -28,6 +28,7 @@
#include "vrml2_faceset.h" #include "vrml2_faceset.h"
#include "vrml2_coords.h" #include "vrml2_coords.h"
#include "vrml2_color.h" #include "vrml2_color.h"
#include "wrlfacet.h"
#include "plugins/3dapi/ifsg_all.h" #include "plugins/3dapi/ifsg_all.h"
@ -78,7 +79,8 @@ void WRL2FACESET::setDefaults( void )
normalPerVertex = true; normalPerVertex = true;
solid = true; solid = true;
creaseAngle = 0.0; creaseAngle = 0.5;
creaseLimit = 0.878; // approx cos( 0.5 )
} }
@ -476,6 +478,13 @@ bool WRL2FACESET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
return false; return false;
} }
if( creaseAngle < 0.0 )
creaseAngle = 0.0;
else if( creaseAngle > M_PI_2 )
creaseAngle = M_PI_2;
creaseLimit = cosf( creaseAngle );
} }
else if( !glob.compare( "colorIndex" ) ) else if( !glob.compare( "colorIndex" ) )
{ {
@ -587,7 +596,7 @@ bool WRL2FACESET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent )
{ {
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
@ -633,12 +642,6 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
if( NULL == coord || vsize < 3 ) if( NULL == coord || vsize < 3 )
return NULL; return NULL;
// create the index list and make sure we have >3 points
size_t idx;
int i1 = coordIndex[0];
int i2 = coordIndex[1];
int i3 = coordIndex[2];
WRLVEC3F* pcoords; WRLVEC3F* pcoords;
size_t coordsize; size_t coordsize;
((WRL2COORDS*) coord)->GetCoords( pcoords, coordsize ); ((WRL2COORDS*) coord)->GetCoords( pcoords, coordsize );
@ -647,7 +650,7 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL; return NULL;
// check that all indices are valid // check that all indices are valid
for( idx = 0; idx < vsize; ++idx ) for( size_t idx = 0; idx < vsize; ++idx )
{ {
if( coordIndex[idx] < 0 ) if( coordIndex[idx] < 0 )
continue; continue;
@ -656,320 +659,129 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL; return NULL;
} }
// if the indices are defective just give up SHAPE lShape;
if( i1 < 0 || i2 < 0 || i3 < 0 FACET* fp = NULL;
|| i1 == i2 || i1 == i3 || i2 == i3 ) size_t iCoord;
return NULL; int idx; // coordinate index
size_t cidx = 0; // color index
std::vector< SGPOINT > lCPts; // coordinate points for SG node SGCOLOR pc1;
std::vector< int > lCIdx; // coordinate index list for SG node (must be triads)
std::vector< SGVECTOR > lCNorm; // per-vertex normals
std::vector< int > faces; // tracks the number of polygons for the entire set
std::vector< SGCOLOR > lColors; // colors points (if any) for SG node
int nfaces = 0; // number of triangles for each face in the list
if( NULL == color ) if( NULL == color )
{ {
// assuming convex polygons, create triangles for the SG node // no per-vertex colors; we can save a few CPU cycles
for( idx = 3; idx <= vsize; ) for( iCoord = 0; iCoord < vsize; ++iCoord )
{ {
lCIdx.push_back( i1 ); idx = coordIndex[iCoord];
if( ccw ) if( idx < 0 )
{ {
lCIdx.push_back( i2 ); if( NULL != fp )
lCIdx.push_back( i3 );
}
else
{
lCIdx.push_back( i3 );
lCIdx.push_back( i2 );
}
++nfaces;
i2 = i3;
if( idx == vsize )
break;
i3 = coordIndex[idx++];
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
{
if( i3 < 0 )
{ {
faces.push_back( nfaces ); if( fp->HasMinPoints() )
nfaces = 0; fp = NULL;
else
fp->Init();
} }
i1 = i2; continue;
i2 = i3;
i3 = coordIndex[idx++];
// any invalid polygons shall void the entire faceset; this is a requirement
// to ensure correct handling of the normals
if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) )
return NULL;
} }
if( i1 < 0 || i2 < 0 || i3 < 0 ) // if the coordinate is bad then skip it
break; if( idx >= (int)coordsize )
continue;
if( NULL == fp )
fp = lShape.NewFacet();
// push the vertex value and index
fp->AddVertex( pcoords[idx], idx );
} }
} }
else else
{ {
int cIndex;
WRL2COLOR* cn = (WRL2COLOR*) color; WRL2COLOR* cn = (WRL2COLOR*) color;
SGCOLOR pc1, pc2, pc3;
WRLVEC3F tc; WRLVEC3F tc;
if( colorPerVertex ) for( iCoord = 0; iCoord < vsize; ++iCoord )
{ {
cIndex = 3; idx = coordIndex[iCoord];
if( colorIndex.empty() ) if( idx < 0 )
{ {
cn->GetColor( coordIndex[0], tc.x, tc.y, tc.z ); if( NULL != fp )
pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[1], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[2], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else
{
if( colorIndex.size() < coordIndex.size() )
{ {
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 ) if( fp->HasMinPoints() )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; fp = NULL;
std::cerr << " * [INFO] bad file; colorIndex.size() < coordIndex.size()\n"; else
#endif fp->Init();
return NULL;
} }
cn->GetColor( colorIndex[0], tc.x, tc.y, tc.z ); if( !colorPerVertex )
pc1.SetColor( tc.x, tc.y, tc.z ); ++cidx;
cn->GetColor( colorIndex[1], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( colorIndex[2], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
}
else
{
cIndex = 1;
if( colorIndex.empty() ) continue;
{
cn->GetColor( 0, tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else
{
cn->GetColor( colorIndex[0], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
}
// assuming convex polygons, create triangles for the SG node
int cMaxIdx = (int) colorIndex.size();
for( idx = 3; idx <= vsize; )
{
lCIdx.push_back( i1 );
lColors.push_back( pc1 );
lColors.push_back( pc2 );
lColors.push_back( pc3 );
if( ccw )
{
lCIdx.push_back( i2 );
lCIdx.push_back( i3 );
}
else
{
lCIdx.push_back( i3 );
lCIdx.push_back( i2 );
} }
++nfaces; // if the coordinate is bad then skip it
i2 = i3; if( idx >= (int)coordsize )
continue;
if( colorPerVertex && i1 >= 0 && i2 >= 0 && i3 >= 0 ) if( NULL == fp )
fp = lShape.NewFacet();
// push the vertex value and index
fp->AddVertex( pcoords[idx], idx );
// push the color if appropriate
if( !colorPerVertex )
{ {
pc1.SetColor( pc2 );
pc2.SetColor( pc3 );
if( colorIndex.empty() ) if( colorIndex.empty() )
{ {
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); cn->GetColor( cidx, tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z ); pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); fp->AddColor( pc1 );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
} }
else else
cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
if( idx == vsize )
break;
i3 = coordIndex[idx++];
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
{
if( i3 < 0 )
{ {
faces.push_back( nfaces ); if( cidx < colorIndex.size() )
nfaces = 0; cn->GetColor( colorIndex[cidx], tc.x, tc.y, tc.z );
if( !colorPerVertex )
{
if( colorIndex.empty() || cIndex >= cMaxIdx )
cn->GetColor( cIndex++, tc.x, tc.y, tc.z );
else
cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
}
i1 = i2;
i2 = i3;
if( colorPerVertex )
{
pc1.SetColor( pc2 );
pc2.SetColor( pc3 );
if( colorIndex.empty() )
{
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else else
cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z ); cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z ); pc1.SetColor( tc.x, tc.y, tc.z );
} fp->AddColor( pc1 );
i3 = coordIndex[idx++];
// any invalid polygons shall void the entire faceset; this is a requirement
// to ensure correct handling of the normals
if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) )
return NULL;
}
if( i1 < 0 || i2 < 0 || i3 < 0 )
break;
}
}
if( lCIdx.empty() )
return NULL;
if( calcNormals || NULL == normal )
{
// create a vertex list for per-face per-vertex normals
std::vector< int >::iterator sI = lCIdx.begin();
std::vector< int >::iterator eI = lCIdx.end();
while( sI != eI )
{
lCPts.push_back( SGPOINT( pcoords[*sI].x, pcoords[*sI].y, pcoords[*sI].z ) );
++sI;
}
for( size_t i = 0; i < lCPts.size(); i += 3 )
{
SGVECTOR sv = S3D::CalcTriNorm( lCPts[i], lCPts[i+1], lCPts[i+2] );
lCNorm.push_back( sv );
lCNorm.push_back( sv );
lCNorm.push_back( sv );
}
}
else
{
// XXX - TO IMPLEMENT
return NULL;
/*
// use the vertex list as is
if( normalPerVertex )
{
// normalPerVertex = TRUE
// rules:
// + if normalIndex is not EMPTY, it is used to select a normal for each vertex
// + if normalIndex is EMPTY, the normal list is used in order per vertex
if( normalIndex.empty() )
{
for( size_t i = 0; i < coordsize; ++i )
{
lCPts.push_back( SGPOINT( pcoords[i].x, pcoords[i].y, pcoords[i].z ) );
// XXX - TO IMPLEMENT
}
}
else
{
// XXX - TO IMPLEMENT: index the normals
} }
} }
else else
{ {
// normalPerVertex = FALSE if( colorIndex.empty() )
// rules: {
// + if normalIndex is not EMPTY, it is used to select a normal for each face cn->GetColor( idx, tc.x, tc.y, tc.z );
// + if normalIndex is EMPTY, the normal list is used in order per face pc1.SetColor( tc.x, tc.y, tc.z );
fp->AddColor( pc1 );
}
else
{
if( iCoord < colorIndex.size() )
cn->GetColor( colorIndex[iCoord], tc.x, tc.y, tc.z );
else
cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
fp->AddColor( pc1 );
}
} }
//*/ }
} }
IFSG_FACESET fsNode( aParent ); SGNODE* np = NULL;
IFSG_COORDS cpNode( fsNode );
cpNode.SetCoordsList( lCPts.size(), &lCPts[0] );
IFSG_COORDINDEX ciNode( fsNode );
if( calcNormals || NULL == normal ) if( ccw )
{ np = lShape.CalcShape( aParent, NULL, ORD_CCW, creaseLimit, true );
for( int i = 0; i < (int)lCPts.size(); ++i )
ciNode.AddIndex( i );
}
else else
{ np = lShape.CalcShape( aParent, NULL, ORD_CLOCKWISE, creaseLimit, true );
ciNode.SetIndices( lCIdx.size(), &lCIdx[0] );
}
IFSG_NORMALS nmNode( fsNode ); return np;
nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
if( !lColors.empty() )
{
IFSG_COLORS nmColor( fsNode );
nmColor.SetColorList( lColors.size(), &lColors[0] );
}
m_sgNode = fsNode.GetRawPtr();
return m_sgNode;
} }

View File

@ -58,6 +58,7 @@ private:
std::vector< int > normalIndex; std::vector< int > normalIndex;
float creaseAngle; float creaseAngle;
float creaseLimit;
/** /**
@ -87,7 +88,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
/** /**
* Function HasColors * Function HasColors

View File

@ -377,7 +377,7 @@ bool WRL2LINESET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2LINESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2LINESET::TranslateToSG( SGNODE* aParent )
{ {
// note: there are no plans to support drawing of lines // note: there are no plans to support drawing of lines
return NULL; return NULL;

View File

@ -77,7 +77,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
/** /**
* Function HasColors * Function HasColors

View File

@ -296,7 +296,7 @@ bool WRL2MATERIAL::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent )
{ {
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );

View File

@ -63,7 +63,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_MATERIAL_H #endif // VRML2_MATERIAL_H

View File

@ -185,7 +185,7 @@ public:
* @param aParent is a pointer to the parent SG node * @param aParent is a pointer to the parent SG node
* @return is non-NULL on success * @return is non-NULL on success
*/ */
virtual SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ) = 0; virtual SGNODE* TranslateToSG( SGNODE* aParent ) = 0;
}; };
#endif // VRML2_NODE_H #endif // VRML2_NODE_H

View File

@ -192,7 +192,7 @@ bool WRL2NORMS::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2NORMS::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2NORMS::TranslateToSG( SGNODE* aParent )
{ {
// any data manipulation must be performed by the parent node // any data manipulation must be performed by the parent node
return NULL; return NULL;

View File

@ -58,7 +58,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_NORMS_H #endif // VRML2_NORMS_H

View File

@ -325,7 +325,7 @@ bool WRL2POINTSET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2POINTSET::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2POINTSET::TranslateToSG( SGNODE* aParent )
{ {
// note: there are no plans to support drawing of points // note: there are no plans to support drawing of points
return NULL; return NULL;

View File

@ -72,7 +72,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
/** /**
* Function HasColors * Function HasColors

View File

@ -326,7 +326,7 @@ bool WRL2SHAPE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent )
{ {
if( NULL == geometry ) if( NULL == geometry )
return NULL; return NULL;
@ -401,11 +401,11 @@ SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
IFSG_SHAPE shNode( aParent ); IFSG_SHAPE shNode( aParent );
SGNODE* pShape = shNode.GetRawPtr(); SGNODE* pShape = shNode.GetRawPtr();
SGNODE* pGeom = geometry->TranslateToSG( pShape, calcNormals ); SGNODE* pGeom = geometry->TranslateToSG( pShape );
SGNODE* pApp = NULL; SGNODE* pApp = NULL;
if( NULL != appearance ) if( NULL != appearance )
pApp = appearance->TranslateToSG( pShape, calcNormals ); pApp = appearance->TranslateToSG( pShape );
if( ( NULL != appearance && NULL == pApp ) || NULL == pGeom ) if( ( NULL != appearance && NULL == pApp ) || NULL == pGeom )
{ {

View File

@ -67,7 +67,7 @@ public:
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_SHAPE_H #endif // VRML2_SHAPE_H

View File

@ -273,7 +273,7 @@ bool WRL2SWITCH::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent )
{ {
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 ) #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating Switch with " << m_Children.size(); std::cerr << " * [INFO] Translating Switch with " << m_Children.size();
@ -327,5 +327,5 @@ SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL; return NULL;
} }
return choices[whichChoice]->TranslateToSG( aParent, calcNormals ); return choices[whichChoice]->TranslateToSG( aParent );
} }

View File

@ -58,7 +58,7 @@ public:
// functions inherited from WRL2NODE // functions inherited from WRL2NODE
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_SWITCH_H #endif // VRML2_SWITCH_H

View File

@ -363,7 +363,7 @@ bool WRL2TRANSFORM::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
} }
SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals ) SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent )
{ {
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 ) #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating Transform with " << m_Children.size(); std::cerr << " * [INFO] Translating Transform with " << m_Children.size();
@ -432,7 +432,7 @@ SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals )
case WRL2_INLINE: case WRL2_INLINE:
case WRL2_TRANSFORM: case WRL2_TRANSFORM:
if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr(), calcNormals ) ) if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr() ) )
test = true; test = true;
break; break;

View File

@ -63,7 +63,7 @@ public:
// functions inherited from WRL2NODE // functions inherited from WRL2NODE
bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode ); bool AddRefNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); SGNODE* TranslateToSG( SGNODE* aParent );
}; };
#endif // VRML2_TRANSFORM_H #endif // VRML2_TRANSFORM_H

View File

@ -252,7 +252,7 @@ SCENEGRAPH* Load( char const* aFileName )
#endif #endif
// for now we recalculate all normals per-vertex per-face // for now we recalculate all normals per-vertex per-face
scene = (SCENEGRAPH*)bp->TranslateToSG( NULL, true ); scene = (SCENEGRAPH*)bp->TranslateToSG( NULL );
} }
delete bp; delete bp;

View File

@ -27,14 +27,13 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <cmath> #include <cmath>
#include <iostream>
#include "wrlfacet.h" #include "wrlfacet.h"
static bool VDegenerate( glm::vec3* pts ) static bool VDegenerate( glm::vec3* pts )
{ {
// note: only checks the degenerate case of zero length sized; it // note: only checks the degenerate case of zero length sides; it
// does not detect the case of 3 distinct collinear points // does not detect the case of 3 distinct collinear points
double dx, dy, dz; double dx, dy, dz;
@ -43,21 +42,21 @@ static bool VDegenerate( glm::vec3* pts )
dy = pts[1].y - pts[0].y; dy = pts[1].y - pts[0].y;
dz = pts[1].z - pts[0].z; dz = pts[1].z - pts[0].z;
if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 )
return true; return true;
dx = pts[2].x - pts[0].x; dx = pts[2].x - pts[0].x;
dy = pts[2].y - pts[0].y; dy = pts[2].y - pts[0].y;
dz = pts[2].z - pts[0].z; dz = pts[2].z - pts[0].z;
if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 )
return true; return true;
dx = pts[2].x - pts[1].x; dx = pts[2].x - pts[1].x;
dy = pts[2].y - pts[1].y; dy = pts[2].y - pts[1].y;
dz = pts[2].z - pts[1].z; dz = pts[2].z - pts[1].z;
if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 )
return true; return true;
return false; return false;
@ -106,17 +105,17 @@ static float VCalcAreaSq( const WRLVEC3F& p1, const WRLVEC3F& p2, const WRLVEC3F
dx = p2.x - p1.x; dx = p2.x - p1.x;
dy = p2.y - p1.y; dy = p2.y - p1.y;
dz = p2.z - p1.z; dz = p2.z - p1.z;
float a = sqrt( dx*dx + dy*dy + dz*dz ); float a = sqrtf( dx*dx + dy*dy + dz*dz );
dx = p3.x - p2.x; dx = p3.x - p2.x;
dy = p3.y - p2.y; dy = p3.y - p2.y;
dz = p3.z - p2.z; dz = p3.z - p2.z;
float b = sqrt( dx*dx + dy*dy + dz*dz ); float b = sqrtf( dx*dx + dy*dy + dz*dz );
dx = p3.x - p1.x; dx = p3.x - p1.x;
dy = p3.y - p1.y; dy = p3.y - p1.y;
dz = p3.z - p1.z; dz = p3.z - p1.z;
float c = sqrt( dx*dx + dy*dy + dz*dz ); float c = sqrtf( dx*dx + dy*dy + dz*dz );
float s = (a + b + c) * 0.5; float s = (a + b + c) * 0.5;
@ -349,7 +348,7 @@ void FACET::CalcVertexNormal( int aIndex, std::list< FACET* > &aFacetList, float
continue; continue;
} }
// check the create angle limit // check the crease angle limit
(*sF)->GetFaceNormal( fp[1] ); (*sF)->GetFaceNormal( fp[1] );
float thrs = VCalcCosAngle( fp[0], face_normal, fp[1] ); float thrs = VCalcCosAngle( fp[0], face_normal, fp[1] );
@ -368,11 +367,16 @@ void FACET::CalcVertexNormal( int aIndex, std::list< FACET* > &aFacetList, float
} }
// normalize the vector // normalize the vector
glm::vec3 tri = glm::vec3( norms[idx].x, norms[idx].y, norms[idx].z ); float dn = sqrtf( norms[idx].x * norms[idx].x
normalize( tri ); + norms[idx].y * norms[idx].y
norms[idx].x = tri.x; + norms[idx].z * norms[idx].z );
norms[idx].y = tri.y;
norms[idx].z = tri.z; if( dn > FLT_EPSILON )
{
norms[idx].x /= dn;
norms[idx].y /= dn;
norms[idx].z /= dn;
}
return; return;
} }
@ -685,7 +689,7 @@ FACET* SHAPE::NewFacet()
SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder, SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder,
float aCreaseLimit ) float aCreaseLimit, bool isVRML2 )
{ {
if( facets.empty() || !facets.front()->HasMinPoints() ) if( facets.empty() || !facets.front()->HasMinPoints() )
return NULL; return NULL;
@ -760,14 +764,19 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd
if( vertices.size() < 3 ) if( vertices.size() < 3 )
return NULL; return NULL;
IFSG_SHAPE shapeNode( aParent ); IFSG_SHAPE shapeNode( false );
if( aColor ) if( !isVRML2 )
{ {
if( NULL == S3D::GetSGNodeParent( aColor ) ) shapeNode.NewNode( aParent );
shapeNode.AddChildNode( aColor );
else if( aColor )
shapeNode.AddRefNode( aColor ); {
if( NULL == S3D::GetSGNodeParent( aColor ) )
shapeNode.AddChildNode( aColor );
else
shapeNode.AddRefNode( aColor );
}
} }
std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format
@ -787,7 +796,13 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd
vertices.clear(); vertices.clear();
normals.clear(); normals.clear();
IFSG_FACESET fsNode( shapeNode ); IFSG_FACESET fsNode( false );
if( !isVRML2 )
fsNode.NewNode( shapeNode );
else
fsNode.NewNode( aParent );
IFSG_COORDS cpNode( fsNode ); IFSG_COORDS cpNode( fsNode );
cpNode.SetCoordsList( lCPts.size(), &lCPts[0] ); cpNode.SetCoordsList( lCPts.size(), &lCPts[0] );
IFSG_COORDINDEX ciNode( fsNode ); IFSG_COORDINDEX ciNode( fsNode );
@ -805,5 +820,8 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd
colors.clear(); colors.clear();
} }
if( !isVRML2 )
return shapeNode.GetRawPtr();
return fsNode.GetRawPtr(); return fsNode.GetRawPtr();
} }

View File

@ -142,7 +142,7 @@ public:
FACET* NewFacet(); FACET* NewFacet();
SGNODE* CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder, SGNODE* CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder,
float aCreaseAngle = 0.5235983 ); float aCreaseLimit = 0.878, bool isVRML2 = false );
}; };
#endif // WRLFACET_H #endif // WRLFACET_H