+ Fixed bug in SGSHAPE::Prepare() : bad assignment of color pointer

+ Reworked s3d_plugin_demo2.cpp to use per-vertex-per-face normals
+ Reworked s3d_plugin_idf.cpp to use per-vertex-per-face normals
This commit is contained in:
Cirilo Bernardo 2015-12-17 13:55:35 +11:00
parent eab70be17b
commit 008d8a540a
14 changed files with 288 additions and 153 deletions

View File

@ -40,6 +40,7 @@
#include "3d_cache/sg/sg_normals.h" #include "3d_cache/sg/sg_normals.h"
#include "3d_cache/sg/sg_shape.h" #include "3d_cache/sg/sg_shape.h"
#include "3d_cache/sg/sg_version.h" #include "3d_cache/sg/sg_version.h"
#include "3d_cache/sg/sg_helpers.h"
#include "3d_info.h" #include "3d_info.h"
#include "plugins/3dapi/c3dmodel.h" #include "plugins/3dapi/c3dmodel.h"
@ -437,3 +438,24 @@ void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor,
return; return;
} }
SGVECTOR S3D::CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT& p3 )
{
glm::dvec3 tri = glm::dvec3( 0.0, 0.0, 0.0 );
glm::dvec3 pts[3];
pts[0] = glm::dvec3( p1.x, p1.y, p1.z );
pts[1] = glm::dvec3( p2.x, p2.y, p2.z );
pts[2] = glm::dvec3( p3.x, p3.y, p3.z );
// degenerate points are given a default 0, 0, 1 normal
if( S3D::degenerate( pts ) )
return SGVECTOR( 0.0, 0.0, 1.0 );
// normal
tri = cross( pts[1] - pts[0], pts[2] - pts[0] );
normalize( tri );
return SGVECTOR( tri.x, tri.y, tri.z );
}

View File

@ -316,33 +316,48 @@ bool SGCOORDS::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
} }
bool SGCOORDS::CalcNormals( SGNODE** aPtr ) bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
{ {
if( aPtr ) if( aPtr )
*aPtr = NULL; *aPtr = NULL;
if( NULL == m_Parent ) if( NULL == m_Parent || NULL == callingNode )
return false; return false;
// the parent and all references must have indices; collect all // the parent and all references must have indices; collect all
// indices into one std::vector<> // indices into one std::vector<>
std::vector< int > ilist; std::vector< int > ilist;
((SGFACESET*)m_Parent)->GatherCoordIndices( ilist ); SGNORMALS* np = NULL;
std::list< SGNODE* >::iterator sB = m_BackPointers.begin(); if( callingNode == m_Parent )
std::list< SGNODE* >::iterator eB = m_BackPointers.end();
while( sB != eB )
{ {
SGFACESET* fp = (SGFACESET*)(*sB); ((SGFACESET*)m_Parent)->GatherCoordIndices( ilist );
fp->GatherCoordIndices( ilist );
++sB; std::list< SGNODE* >::iterator sB = m_BackPointers.begin();
std::list< SGNODE* >::iterator eB = m_BackPointers.end();
while( sB != eB )
{
SGFACESET* fp = (SGFACESET*)(*sB);
fp->GatherCoordIndices( ilist );
++sB;
}
np = ((SGFACESET*)m_Parent)->m_Normals;
if( !np )
np = new SGNORMALS( m_Parent );
} }
else
{
callingNode->GatherCoordIndices( ilist );
np = callingNode->m_Normals;
SGNORMALS* np = ((SGFACESET*)m_Parent)->m_Normals; if( !np )
np = new SGNORMALS( callingNode );
if( !np ) }
np = new SGNORMALS( m_Parent );
if( S3D::CalcTriangleNormals( coords, ilist, np->norms ) ) if( S3D::CalcTriangleNormals( coords, ilist, np->norms ) )
{ {

View File

@ -32,6 +32,8 @@
#include <vector> #include <vector>
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
class SGFACESET;
class SGCOORDS : public SGNODE class SGCOORDS : public SGNODE
{ {
public: public:
@ -60,7 +62,7 @@ public:
* calculates normals for this coordinate list and sets the * calculates normals for this coordinate list and sets the
* normals list in the parent SGFACESET * normals list in the parent SGFACESET
*/ */
bool CalcNormals( SGNODE** aPtr ); bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = NULL );
void ReNameNodes( void ); void ReNameNodes( void );
bool WriteVRML( std::ofstream& aFile, bool aReuseFlag ); bool WriteVRML( std::ofstream& aFile, bool aReuseFlag );

View File

@ -1043,21 +1043,19 @@ void SGFACESET::GatherCoordIndices( std::vector< int >& aIndexList )
bool SGFACESET::CalcNormals( SGNODE** aPtr ) bool SGFACESET::CalcNormals( SGNODE** aPtr )
{ {
SGCOORDS* coords = m_Coords;
if( m_RCoords ) if( m_RCoords )
{ coords = m_RCoords;
SGFACESET* fp = (SGFACESET*) m_RCoords->GetParent();
if( !fp ) if( NULL == coords || coords->coords.empty() )
return false;
return fp->CalcNormals( aPtr );
}
if( NULL == m_Coords || m_Coords->coords.empty() )
return false; return false;
if( m_Normals && !m_Normals->norms.empty( ) ) if( m_Normals && !m_Normals->norms.empty( ) )
return true; return true;
return m_Coords->CalcNormals( aPtr ); if( m_RNormals && !m_RNormals->norms.empty( ) )
return true;
return coords->CalcNormals( this, aPtr );
} }

View File

@ -32,7 +32,6 @@
#include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_helpers.h"
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
#include <glm/glm.hpp>
// formats a floating point number for text output to a VRML file // formats a floating point number for text output to a VRML file
@ -311,7 +310,7 @@ bool S3D::ReadColor( std::ifstream& aFile, SGCOLOR& aColor )
} }
static bool degenerate( glm::dvec3* pts ) bool S3D::degenerate( glm::dvec3* pts )
{ {
double dx, dy, dz; double dx, dy, dz;
@ -342,7 +341,7 @@ static bool degenerate( glm::dvec3* pts )
static void calcTriad( glm::dvec3* pts, glm::dvec3& tri ) static void calcTriad( glm::dvec3* pts, glm::dvec3& tri )
{ {
if( degenerate( pts ) ) if( S3D::degenerate( pts ) )
{ {
// degenerate points should contribute nothing to the result // degenerate points should contribute nothing to the result
tri = glm::dvec3( 0.0, 0.0, 0.0 ); tri = glm::dvec3( 0.0, 0.0, 0.0 );

View File

@ -38,6 +38,7 @@
#include <vector> #include <vector>
#include "plugins/3dapi/sg_base.h" #include "plugins/3dapi/sg_base.h"
#include "plugins/3dapi/sg_types.h" #include "plugins/3dapi/sg_types.h"
#include <glm/glm.hpp>
class SGNORMALS; class SGNORMALS;
class SGCOORDS; class SGCOORDS;
@ -153,6 +154,8 @@ class SGCOORDINDEX;
namespace S3D namespace S3D
{ {
bool degenerate( glm::dvec3* pts );
// //
// Normals calculations from triangles // Normals calculations from triangles
// //

View File

@ -605,7 +605,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
return true; return true;
} }
if( NULL == m_Appearance ) if( NULL == pa )
{ {
m.m_MaterialIdx = 0; m.m_MaterialIdx = 0;
} }

View File

@ -281,7 +281,7 @@ void C3D_MODEL_VIEWER::OnPaint( wxPaintEvent &event )
m_ogl_3dmodel->Draw_opaque(); m_ogl_3dmodel->Draw_opaque();
//m_ogl_3dmodel->Draw_transparent(); //m_ogl_3dmodel->Draw_transparent();
m_ogl_3dmodel->Draw_bboxes(); //m_ogl_3dmodel->Draw_bboxes();
glPopMatrix(); glPopMatrix();
} }

View File

@ -42,6 +42,12 @@ struct S3D_POINT;
namespace S3D namespace S3D
{ {
/**
* Function CalcTriNorm
* returns the normal vector of a triangle described by vertices p1, p2, p3
*/
SGLIB_API SGVECTOR CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT& p3 );
/** /**
* Function WriteCache * Function WriteCache
* writes the SGNODE tree to a binary cache file * writes the SGNODE tree to a binary cache file

View File

@ -1,3 +1,3 @@
#add_subdirectory( demo ) add_subdirectory( demo )
add_subdirectory( idf ) add_subdirectory( idf )
add_subdirectory( vrml ) add_subdirectory( vrml )

View File

@ -136,33 +136,31 @@ bool CanRender( void )
SCENEGRAPH* Load( char const* aFileName ) SCENEGRAPH* Load( char const* aFileName )
{ {
// For this demonstration we create a tetrahedron and // For this demonstration we create a tetrahedron (tx1) consisting of a SCENEGRAPH
// paint its faces Magenta Red Green Blue. Steps: // (VRML Transform) which in turn contains 4 SGSHAPE (VRML Shape) objects
// * Create a top level transform tx0 which represent the VRML file // representing each of the sides of the tetrahedron. Each Shape is associated
// * Create a child transform tx1, parent tx0, to define the tetrahedron // with a color (SGAPPEARANCE) and a SGFACESET (VRML Geometry->indexedFaceSet).
// + Create 'shape' to define one facet // Each SGFACESET is associated with a vertex list (SGCOORDS), a per-vertex normals
// ++ Create a 'face' to hold vertices and indices // list (SGNORMALS), and a coordinate index (SGCOORDINDEX). One shape is used to
// +++ Create 'cp' which is the coordinate list // represent each face so that we may use per-vertex-per-face normals.
// +++ Create 'np' which is the per-vertex normals list //
// +++ Create 'coordIndex' which is the (triangular) vertex index list // The tetrahedron in turn is a child of a top level SCENEGRAPH (tx0) which has
// for facet1 of the tetrahedron // a second SCENEGRAPH child (tx2) which is a transformation of the tetrahedron tx1
// ++ Create a 'material' to define the appearance of 'shape' // (rotation + translation). This demonstrates the reuse of components within
// ** // the model heirarchy.
// + shape->NewNode() to define next facet
// ++ face->NewNode() for a new facet // define the vertices of the tetrahedron
// +++ Add Ref to 'cp' for coordinate list // face 1: 0, 3, 1
// +++ Add Ref to 'np' for normals list // face 2: 0, 2, 3
// +++ coordIndex->NewNode() for vertex index list of new facet // face 3: 1, 3, 2
// ++ material->NewNode() for material of new facet // face 4: 0, 1, 2
// + repeat twice from ** to produce last 2 facets double SQ2 = sqrt( 0.5 );
// * Create a child transform tx2, parent tx0, for a referenced tetrahedron SGPOINT vert[4];
// + Set a translation and rotation so that this is distinct from tx1 vert[0] = SGPOINT( 1.0, 0.0, -SQ2 );
// + Add Reference to tx1 vert[1] = SGPOINT( -1.0, 0.0, -SQ2 );
// ALL DONE: we now have: vert[2] = SGPOINT( 0.0, 1.0, SQ2 );
// tx0 vert[3] = SGPOINT( 0.0, -1.0, SQ2 );
// - contains tx1 which contains all elements of a tetrahedron
// - contains tx0 which contains a reference to tx1 and offsets it so
// that it renders in a different position
// create the top level transform; this will hold all other // create the top level transform; this will hold all other
// scenegraph objects; a transform may hold other transforms and // scenegraph objects; a transform may hold other transforms and
@ -172,7 +170,7 @@ SCENEGRAPH* Load( char const* aFileName )
// create the transform which will house the shapes // create the transform which will house the shapes
IFSG_TRANSFORM* tx1 = new IFSG_TRANSFORM( tx0->GetRawPtr() ); IFSG_TRANSFORM* tx1 = new IFSG_TRANSFORM( tx0->GetRawPtr() );
// add a shape which we will use to define a tetrahedron; shapes // add a shape which we will use to define one face of the tetrahedron; shapes
// hold facesets and appearances // hold facesets and appearances
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx1 ); IFSG_SHAPE* shape = new IFSG_SHAPE( *tx1 );
@ -182,30 +180,19 @@ SCENEGRAPH* Load( char const* aFileName )
IFSG_FACESET* face = new IFSG_FACESET( *shape ); IFSG_FACESET* face = new IFSG_FACESET( *shape );
// define the vertices of the tetrahedron
double SQ2 = sqrt( 0.5 );
SGPOINT vert[4];
vert[0] = SGPOINT( 1.0, 0.0, -SQ2 );
vert[1] = SGPOINT( -1.0, 0.0, -SQ2 );
vert[2] = SGPOINT( 0.0, 1.0, SQ2 );
vert[3] = SGPOINT( 0.0, -1.0, SQ2 );
IFSG_COORDS* cp = new IFSG_COORDS( *face ); IFSG_COORDS* cp = new IFSG_COORDS( *face );
cp->SetCoordsList( 4, vert ); cp->AddCoord( vert[0] );
cp->AddCoord( vert[3] );
cp->AddCoord( vert[1] );
// coordinate indices - note: enforce triangles; // coordinate indices - note: enforce triangles;
// in real plugins where it is not necessarily possible // in real plugins where it is not necessarily possible
// to determine which side a triangle is visible from, // to determine which side a triangle is visible from,
// 2 point orders must be specified for each triangle // 2 point orders must be specified for each triangle
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face );
int cidx[12] = { 0, 3, 1, 0, 2, 3, 1, 3, 2, 0, 1, 2 }; coordIdx->AddIndex( 0 );
coordIdx->SetIndices( 3, cidx ); coordIdx->AddIndex( 1 );
coordIdx->AddIndex( 2 );
// note: track the sets of faces since all faces need to be
// instantiated before we can calculate the normals list;
// this is due to the need for all vertices to be referenced
// in the index lists; however we have a single coordinate
// list and 4 associated vertex lists so the requirement is
// not met until all faces are instantiated.
SGNODE* face1 = face->GetRawPtr();
// create an appearance; appearances are owned by shapes // create an appearance; appearances are owned by shapes
// magenta // magenta
@ -215,64 +202,99 @@ SCENEGRAPH* Load( char const* aFileName )
material->SetAmbient( 0.9 ); material->SetAmbient( 0.9 );
material->SetShininess( 0.3 ); material->SetShininess( 0.3 );
// normals
IFSG_NORMALS* np = new IFSG_NORMALS( *face );
SGVECTOR nval = S3D::CalcTriNorm( vert[0], vert[3], vert[1] );
np->AddNormal( nval );
np->AddNormal( nval );
np->AddNormal( nval );
//
// Shape2 // Shape2
// Note: we reuse the IFSG* wrappers to create and manipulate new
// data structures.
//
shape->NewNode( *tx1 ); shape->NewNode( *tx1 );
face->NewNode( *shape ); face->NewNode( *shape );
face->AddRefNode( *cp );
coordIdx->NewNode( *face ); coordIdx->NewNode( *face );
coordIdx->SetIndices( 3, &cidx[3] ); cp->NewNode( *face );
SGNODE* face2 = face->GetRawPtr(); np->NewNode( *face );
// red // vertices
cp->AddCoord( vert[0] );
cp->AddCoord( vert[2] );
cp->AddCoord( vert[3] );
// indices
coordIdx->AddIndex( 0 );
coordIdx->AddIndex( 1 );
coordIdx->AddIndex( 2 );
// normals
nval = S3D::CalcTriNorm( vert[0], vert[2], vert[3] );
np->AddNormal( nval );
np->AddNormal( nval );
np->AddNormal( nval );
// color (red)
material->NewNode( *shape ); material->NewNode( *shape );
material->SetSpecular( 1.0, 0.0, 0.0 ); material->SetSpecular( 1.0, 0.0, 0.0 );
material->SetDiffuse( 0.9, 0.0, 0.0 ); material->SetDiffuse( 0.9, 0.0, 0.0 );
material->SetAmbient( 0.9 ); material->SetAmbient( 0.9 );
material->SetShininess( 0.3 ); material->SetShininess( 0.3 );
//
// Shape3 // Shape3
//
shape->NewNode( *tx1 ); shape->NewNode( *tx1 );
face->NewNode( *shape ); face->NewNode( *shape );
face->AddRefNode( *cp );
coordIdx->NewNode( *face ); coordIdx->NewNode( *face );
coordIdx->SetIndices( 3, &cidx[6] ); cp->NewNode( *face );
SGNODE* face3 = face->GetRawPtr(); np->NewNode( *face );
// green // vertices
cp->AddCoord( vert[1] );
cp->AddCoord( vert[3] );
cp->AddCoord( vert[2] );
// indices
coordIdx->AddIndex( 0 );
coordIdx->AddIndex( 1 );
coordIdx->AddIndex( 2 );
// normals
nval = S3D::CalcTriNorm( vert[1], vert[3], vert[2] );
np->AddNormal( nval );
np->AddNormal( nval );
np->AddNormal( nval );
// color (green)
material->NewNode( *shape ); material->NewNode( *shape );
material->SetSpecular( 0.0, 1.0, 0.0 ); material->SetSpecular( 0.0, 1.0, 0.0 );
material->SetDiffuse( 0.0, 0.9, 0.0 ); material->SetDiffuse( 0.0, 0.9, 0.0 );
material->SetAmbient( 0.9 ); material->SetAmbient( 0.9 );
material->SetShininess( 0.3 ); material->SetShininess( 0.3 );
//
// Shape4 // Shape4
//
shape->NewNode( *tx1 ); shape->NewNode( *tx1 );
face->NewNode( *shape ); face->NewNode( *shape );
face->AddRefNode( *cp );
coordIdx->NewNode( *face ); coordIdx->NewNode( *face );
coordIdx->SetIndices( 3, &cidx[9] ); cp->NewNode( *face );
SGNODE* face4 = face->GetRawPtr(); np->NewNode( *face );
// blue // vertices
cp->AddCoord( vert[0] );
cp->AddCoord( vert[1] );
cp->AddCoord( vert[2] );
// indices
coordIdx->AddIndex( 0 );
coordIdx->AddIndex( 1 );
coordIdx->AddIndex( 2 );
// normals
nval = S3D::CalcTriNorm( vert[0], vert[1], vert[2] );
np->AddNormal( nval );
np->AddNormal( nval );
np->AddNormal( nval );
// color (blue)
material->NewNode( *shape ); material->NewNode( *shape );
material->SetSpecular( 0.0, 0.0, 1.0 ); material->SetSpecular( 0.0, 0.0, 1.0 );
material->SetDiffuse( 0.0, 0.0, 0.9 ); material->SetDiffuse( 0.0, 0.0, 0.9 );
material->SetAmbient( 0.9 ); material->SetAmbient( 0.9 );
material->SetShininess( 0.3 ); material->SetShininess( 0.3 );
// note: now that the faces are instantiated we
// can calculate the per-vertex normals
SGNODE* np;
face->Attach( face1 );
face->CalcNormals( &np );
if( np )
{
face->Attach( face2 );
face->AddRefNode( np );
face->Attach( face3 );
face->AddRefNode( np );
face->Attach( face4 );
face->AddRefNode( np );
}
// create a copy of the entire tetrahedron shifted Z+2 and rotated 2/3PI // create a copy of the entire tetrahedron shifted Z+2 and rotated 2/3PI
IFSG_TRANSFORM* tx2 = new IFSG_TRANSFORM( tx0->GetRawPtr() ); IFSG_TRANSFORM* tx2 = new IFSG_TRANSFORM( tx0->GetRawPtr() );
tx2->AddRefNode( *tx1 ); tx2->AddRefNode( *tx1 );
@ -287,6 +309,7 @@ SCENEGRAPH* Load( char const* aFileName )
delete coordIdx; delete coordIdx;
delete material; delete material;
delete cp; delete cp;
delete np;
delete tx0; delete tx0;
delete tx1; delete tx1;
delete tx2; delete tx2;

View File

@ -258,10 +258,11 @@ SCENEGRAPH* Load( char const* aFileName )
vpcb.Tesselate( NULL ); vpcb.Tesselate( NULL );
std::vector< double > vertices; std::vector< double > vertices;
std::vector< int > indices; std::vector< int > idxPlane;
std::vector< int > idxSide;
double thick = outline->GetThickness(); double thick = outline->GetThickness();
if( !vpcb.Get3DTriangles( vertices, indices, thick, 0.0 ) ) if( !vpcb.Get3DTriangles( vertices, idxPlane, idxSide, thick, 0.0 ) )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
@ -271,6 +272,15 @@ SCENEGRAPH* Load( char const* aFileName )
return NULL; return NULL;
} }
if( ( idxPlane.size() % 3 ) || ( idxSide.size() % 3 ) )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] index lists are not a multiple of 3 (not a triangle list)\n";
#endif
return NULL;
}
std::vector< SGPOINT > vlist; std::vector< SGPOINT > vlist;
size_t nvert = vertices.size() / 3; size_t nvert = vertices.size() / 3;
size_t j = 0; size_t j = 0;
@ -279,24 +289,73 @@ SCENEGRAPH* Load( char const* aFileName )
vlist.push_back( SGPOINT( vertices[j], vertices[j+1], vertices[j+2] ) ); vlist.push_back( SGPOINT( vertices[j], vertices[j+1], vertices[j+2] ) );
// create the intermediate scenegraph // create the intermediate scenegraph
IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); // tx0 = top level Transform
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 ); IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 ); // shape will hold (a) all vertices and (b) a local list of normals
IFSG_FACESET* face = new IFSG_FACESET( *shape ); IFSG_FACESET* face = new IFSG_FACESET( *shape ); // this face shall represent the top and bottom planes
IFSG_COORDS* cp = new IFSG_COORDS( *face ); IFSG_COORDS* cp = new IFSG_COORDS( *face ); // coordinates for all faces
cp->SetCoordsList( nvert, &vlist[0] ); cp->SetCoordsList( nvert, &vlist[0] );
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); // coordinate indices for top and bottom planes only
coordIdx->SetIndices( indices.size(), &indices[0] ); coordIdx->SetIndices( idxPlane.size(), &idxPlane[0] );
IFSG_NORMALS* norms = new IFSG_NORMALS( *face ); // normals for the top and bottom planes
if( !face->CalcNormals( NULL ) ) // number of TOP (and bottom) vertices
j = nvert / 2;
// set the TOP normals
for( size_t i = 0; i < j; ++i )
norms->AddNormal( 0.0, 0.0, 1.0 );
// set the BOTTOM normals
for( size_t i = 0; i < j; ++i )
norms->AddNormal( 0.0, 0.0, -1.0 );
// assign a color from the rotating palette
SGNODE* modelColor = getColor( *shape );
// create a second shape describing the vertical walls of the IDF extrusion
// using per-vertex-per-face-normals
shape->NewNode( *tx0 );
shape->AddRefNode( modelColor ); // set the color to be the same as the top/bottom
face->NewNode( *shape );
cp->NewNode( *face ); // new vertex list
norms->NewNode( *face ); // new normals list
coordIdx->NewNode( *face ); // new index list
// populate the new per-face vertex list and its indices and normals
std::vector< int >::iterator sI = idxSide.begin();
std::vector< int >::iterator eI = idxSide.end();
size_t sidx = 0; // index to the new coord set
SGPOINT p1, p2, p3;
SGVECTOR vnorm;
while( sI != eI )
{ {
#ifdef DEBUG p1 = vlist[*sI];
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; cp->AddCoord( p1 );
std::cerr << " * [INFO] cannot calculate normals\n"; ++sI;
#endif
p2 = vlist[*sI];
cp->AddCoord( p2 );
++sI;
p3 = vlist[*sI];
cp->AddCoord( p3 );
++sI;
vnorm.SetVector( S3D::CalcTriNorm( p1, p2, p3 ) );
norms->AddNormal( vnorm );
norms->AddNormal( vnorm );
norms->AddNormal( vnorm );
coordIdx->AddIndex( (int)sidx );
++sidx;
coordIdx->AddIndex( (int)sidx );
++sidx;
coordIdx->AddIndex( (int)sidx );
++sidx;
} }
// magenta
getColor( *shape );
SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr(); SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr();
// DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS // DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS

View File

@ -1793,10 +1793,12 @@ void VRML_LAYER::SetVertexOffsets( double aXoffset, double aYoffset )
bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList, bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
std::vector< int > &aIndexList, double aTopZ, double aBotZ ) std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
double aTopZ, double aBotZ )
{ {
aVertexList.clear(); aVertexList.clear();
aIndexList.clear(); aIndexPlane.clear();
aIndexSide.clear();
if( ordmap.size() < 3 || outline.empty() ) if( ordmap.size() < 3 || outline.empty() )
return false; return false;
@ -1853,20 +1855,24 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
std::list< TRIPLET_3D >::const_iterator tbeg = triplets.begin(); std::list< TRIPLET_3D >::const_iterator tbeg = triplets.begin();
std::list< TRIPLET_3D >::const_iterator tend = triplets.end(); std::list< TRIPLET_3D >::const_iterator tend = triplets.end();
std::vector< int > aIndexBot;
while( tbeg != tend ) while( tbeg != tend )
{ {
// top vertices // top vertices
aIndexList.push_back( (int) tbeg->i1 ); aIndexPlane.push_back( (int) tbeg->i1 );
aIndexList.push_back( (int) tbeg->i2 ); aIndexPlane.push_back( (int) tbeg->i2 );
aIndexList.push_back( (int) tbeg->i3 ); aIndexPlane.push_back( (int) tbeg->i3 );
// bottom vertices // bottom vertices
aIndexList.push_back( (int) ( tbeg->i2 + vsize ) ); aIndexBot.push_back( (int) ( tbeg->i2 + vsize ) );
aIndexList.push_back( (int) ( tbeg->i1 + vsize ) ); aIndexBot.push_back( (int) ( tbeg->i1 + vsize ) );
aIndexList.push_back( (int) ( tbeg->i3 + vsize ) ); aIndexBot.push_back( (int) ( tbeg->i3 + vsize ) );
++tbeg; ++tbeg;
} }
aIndexPlane.insert( aIndexPlane.end(), aIndexBot.begin(), aIndexBot.end() );
} }
// compile indices for the walls joining top to bottom // compile indices for the walls joining top to bottom
@ -1902,23 +1908,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
if( !holes_only ) if( !holes_only )
{ {
aIndexList.push_back( curPoint ); aIndexSide.push_back( curPoint );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) );
} }
else else
{ {
aIndexList.push_back( curPoint ); aIndexSide.push_back( curPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
} }
lastPoint = curPoint; lastPoint = curPoint;
@ -1933,23 +1939,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
if( !holes_only ) if( !holes_only )
{ {
aIndexList.push_back( curPoint ); aIndexSide.push_back( curPoint );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) );
} }
else else
{ {
aIndexList.push_back( curPoint ); aIndexSide.push_back( curPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) );
aIndexList.push_back( lastPoint ); aIndexSide.push_back( lastPoint );
} }
++obeg; ++obeg;

View File

@ -463,12 +463,14 @@ public:
* triangular vertices which may be used for rendering. * triangular vertices which may be used for rendering.
* *
* @param aVertexList will store the vertices * @param aVertexList will store the vertices
* @param aIndexList will store the indices * @param aIndexPlane will store the indices for the top + bottom planes
* @param aIndexSide will store the indices for the vertical wall
* @param aTopZ is the top plane of the model * @param aTopZ is the top plane of the model
* @param aBotZ is the bottom plane of the model * @param aBotZ is the bottom plane of the model
*/ */
bool Get3DTriangles( std::vector< double >& aVertexList, bool Get3DTriangles( std::vector< double >& aVertexList,
std::vector< int > &aIndexList, double aTopZ, double aBotZ ); std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
double aTopZ, double aBotZ );
}; };