diff --git a/3d-viewer/3d_cache/sg/ifsg_api.cpp b/3d-viewer/3d_cache/sg/ifsg_api.cpp index fc902ec9d4..7e620892ad 100644 --- a/3d-viewer/3d_cache/sg/ifsg_api.cpp +++ b/3d-viewer/3d_cache/sg/ifsg_api.cpp @@ -40,6 +40,7 @@ #include "3d_cache/sg/sg_normals.h" #include "3d_cache/sg/sg_shape.h" #include "3d_cache/sg/sg_version.h" +#include "3d_cache/sg/sg_helpers.h" #include "3d_info.h" #include "plugins/3dapi/c3dmodel.h" @@ -437,3 +438,24 @@ void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor, 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 ); +} diff --git a/3d-viewer/3d_cache/sg/sg_coords.cpp b/3d-viewer/3d_cache/sg/sg_coords.cpp index 9e065fcbce..0844280fc1 100644 --- a/3d-viewer/3d_cache/sg/sg_coords.cpp +++ b/3d-viewer/3d_cache/sg/sg_coords.cpp @@ -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 ) *aPtr = NULL; - if( NULL == m_Parent ) + if( NULL == m_Parent || NULL == callingNode ) return false; // the parent and all references must have indices; collect all // indices into one std::vector<> std::vector< int > ilist; - ((SGFACESET*)m_Parent)->GatherCoordIndices( ilist ); + SGNORMALS* np = NULL; - std::list< SGNODE* >::iterator sB = m_BackPointers.begin(); - std::list< SGNODE* >::iterator eB = m_BackPointers.end(); - - while( sB != eB ) + if( callingNode == m_Parent ) { - SGFACESET* fp = (SGFACESET*)(*sB); - fp->GatherCoordIndices( ilist ); - ++sB; + ((SGFACESET*)m_Parent)->GatherCoordIndices( ilist ); + + 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 ) ) { diff --git a/3d-viewer/3d_cache/sg/sg_coords.h b/3d-viewer/3d_cache/sg/sg_coords.h index b1ca5de770..5e5a9f6845 100644 --- a/3d-viewer/3d_cache/sg/sg_coords.h +++ b/3d-viewer/3d_cache/sg/sg_coords.h @@ -32,6 +32,8 @@ #include #include "3d_cache/sg/sg_node.h" +class SGFACESET; + class SGCOORDS : public SGNODE { public: @@ -60,7 +62,7 @@ public: * calculates normals for this coordinate list and sets the * normals list in the parent SGFACESET */ - bool CalcNormals( SGNODE** aPtr ); + bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = NULL ); void ReNameNodes( void ); bool WriteVRML( std::ofstream& aFile, bool aReuseFlag ); diff --git a/3d-viewer/3d_cache/sg/sg_faceset.cpp b/3d-viewer/3d_cache/sg/sg_faceset.cpp index 3f5cb88d6b..e7c391828b 100644 --- a/3d-viewer/3d_cache/sg/sg_faceset.cpp +++ b/3d-viewer/3d_cache/sg/sg_faceset.cpp @@ -1043,21 +1043,19 @@ void SGFACESET::GatherCoordIndices( std::vector< int >& aIndexList ) bool SGFACESET::CalcNormals( SGNODE** aPtr ) { + SGCOORDS* coords = m_Coords; + if( m_RCoords ) - { - SGFACESET* fp = (SGFACESET*) m_RCoords->GetParent(); + coords = m_RCoords; - if( !fp ) - return false; - - return fp->CalcNormals( aPtr ); - } - - if( NULL == m_Coords || m_Coords->coords.empty() ) + if( NULL == coords || coords->coords.empty() ) return false; if( m_Normals && !m_Normals->norms.empty( ) ) return true; - return m_Coords->CalcNormals( aPtr ); + if( m_RNormals && !m_RNormals->norms.empty( ) ) + return true; + + return coords->CalcNormals( this, aPtr ); } diff --git a/3d-viewer/3d_cache/sg/sg_helpers.cpp b/3d-viewer/3d_cache/sg/sg_helpers.cpp index 38828bf73a..f770b3c680 100644 --- a/3d-viewer/3d_cache/sg/sg_helpers.cpp +++ b/3d-viewer/3d_cache/sg/sg_helpers.cpp @@ -32,7 +32,6 @@ #include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_node.h" -#include // 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; @@ -342,7 +341,7 @@ static bool degenerate( glm::dvec3* pts ) static void calcTriad( glm::dvec3* pts, glm::dvec3& tri ) { - if( degenerate( pts ) ) + if( S3D::degenerate( pts ) ) { // degenerate points should contribute nothing to the result tri = glm::dvec3( 0.0, 0.0, 0.0 ); diff --git a/3d-viewer/3d_cache/sg/sg_helpers.h b/3d-viewer/3d_cache/sg/sg_helpers.h index 7cf6ce8f8f..91e0245b35 100644 --- a/3d-viewer/3d_cache/sg/sg_helpers.h +++ b/3d-viewer/3d_cache/sg/sg_helpers.h @@ -38,6 +38,7 @@ #include #include "plugins/3dapi/sg_base.h" #include "plugins/3dapi/sg_types.h" +#include class SGNORMALS; class SGCOORDS; @@ -153,6 +154,8 @@ class SGCOORDINDEX; namespace S3D { + bool degenerate( glm::dvec3* pts ); + // // Normals calculations from triangles // diff --git a/3d-viewer/3d_cache/sg/sg_shape.cpp b/3d-viewer/3d_cache/sg/sg_shape.cpp index 805a28029f..90fbfeaea1 100644 --- a/3d-viewer/3d_cache/sg/sg_shape.cpp +++ b/3d-viewer/3d_cache/sg/sg_shape.cpp @@ -605,7 +605,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform, return true; } - if( NULL == m_Appearance ) + if( NULL == pa ) { m.m_MaterialIdx = 0; } diff --git a/3d-viewer/3d_model_viewer/c3d_model_viewer.cpp b/3d-viewer/3d_model_viewer/c3d_model_viewer.cpp index f0eb4b578e..94065c07b7 100644 --- a/3d-viewer/3d_model_viewer/c3d_model_viewer.cpp +++ b/3d-viewer/3d_model_viewer/c3d_model_viewer.cpp @@ -281,7 +281,7 @@ void C3D_MODEL_VIEWER::OnPaint( wxPaintEvent &event ) m_ogl_3dmodel->Draw_opaque(); //m_ogl_3dmodel->Draw_transparent(); - m_ogl_3dmodel->Draw_bboxes(); + //m_ogl_3dmodel->Draw_bboxes(); glPopMatrix(); } diff --git a/include/plugins/3dapi/ifsg_api.h b/include/plugins/3dapi/ifsg_api.h index 8dea5f4eb5..f06bac3192 100644 --- a/include/plugins/3dapi/ifsg_api.h +++ b/include/plugins/3dapi/ifsg_api.h @@ -42,6 +42,12 @@ struct S3D_POINT; 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 * writes the SGNODE tree to a binary cache file diff --git a/plugins/3d/CMakeLists.txt b/plugins/3d/CMakeLists.txt index e34ff17586..3416f08ab8 100644 --- a/plugins/3d/CMakeLists.txt +++ b/plugins/3d/CMakeLists.txt @@ -1,3 +1,3 @@ -#add_subdirectory( demo ) +add_subdirectory( demo ) add_subdirectory( idf ) add_subdirectory( vrml ) diff --git a/plugins/3d/demo/s3d_plugin_demo2.cpp b/plugins/3d/demo/s3d_plugin_demo2.cpp index 199588e3cf..fa22f63431 100644 --- a/plugins/3d/demo/s3d_plugin_demo2.cpp +++ b/plugins/3d/demo/s3d_plugin_demo2.cpp @@ -136,33 +136,31 @@ bool CanRender( void ) SCENEGRAPH* Load( char const* aFileName ) { - // For this demonstration we create a tetrahedron and - // paint its faces Magenta Red Green Blue. Steps: - // * Create a top level transform tx0 which represent the VRML file - // * Create a child transform tx1, parent tx0, to define the tetrahedron - // + Create 'shape' to define one facet - // ++ Create a 'face' to hold vertices and indices - // +++ Create 'cp' which is the coordinate list - // +++ Create 'np' which is the per-vertex normals list - // +++ Create 'coordIndex' which is the (triangular) vertex index list - // for facet1 of the tetrahedron - // ++ Create a 'material' to define the appearance of 'shape' - // ** - // + shape->NewNode() to define next facet - // ++ face->NewNode() for a new facet - // +++ Add Ref to 'cp' for coordinate list - // +++ Add Ref to 'np' for normals list - // +++ coordIndex->NewNode() for vertex index list of new facet - // ++ material->NewNode() for material of new facet - // + repeat twice from ** to produce last 2 facets - // * Create a child transform tx2, parent tx0, for a referenced tetrahedron - // + Set a translation and rotation so that this is distinct from tx1 - // + Add Reference to tx1 - // ALL DONE: we now have: - // tx0 - // - 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 + // For this demonstration we create a tetrahedron (tx1) consisting of a SCENEGRAPH + // (VRML Transform) which in turn contains 4 SGSHAPE (VRML Shape) objects + // representing each of the sides of the tetrahedron. Each Shape is associated + // with a color (SGAPPEARANCE) and a SGFACESET (VRML Geometry->indexedFaceSet). + // Each SGFACESET is associated with a vertex list (SGCOORDS), a per-vertex normals + // list (SGNORMALS), and a coordinate index (SGCOORDINDEX). One shape is used to + // represent each face so that we may use per-vertex-per-face normals. + // + // The tetrahedron in turn is a child of a top level SCENEGRAPH (tx0) which has + // a second SCENEGRAPH child (tx2) which is a transformation of the tetrahedron tx1 + // (rotation + translation). This demonstrates the reuse of components within + // the model heirarchy. + + // define the vertices of the tetrahedron + // face 1: 0, 3, 1 + // face 2: 0, 2, 3 + // face 3: 1, 3, 2 + // face 4: 0, 1, 2 + 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 ); + // create the top level transform; this will hold all other // 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 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 IFSG_SHAPE* shape = new IFSG_SHAPE( *tx1 ); @@ -182,30 +180,19 @@ SCENEGRAPH* Load( char const* aFileName ) 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 ); - cp->SetCoordsList( 4, vert ); + cp->AddCoord( vert[0] ); + cp->AddCoord( vert[3] ); + cp->AddCoord( vert[1] ); + // coordinate indices - note: enforce triangles; // in real plugins where it is not necessarily possible // to determine which side a triangle is visible from, // 2 point orders must be specified for each triangle IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); - int cidx[12] = { 0, 3, 1, 0, 2, 3, 1, 3, 2, 0, 1, 2 }; - coordIdx->SetIndices( 3, cidx ); - - // 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(); + coordIdx->AddIndex( 0 ); + coordIdx->AddIndex( 1 ); + coordIdx->AddIndex( 2 ); // create an appearance; appearances are owned by shapes // magenta @@ -215,64 +202,99 @@ SCENEGRAPH* Load( char const* aFileName ) material->SetAmbient( 0.9 ); 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 + // Note: we reuse the IFSG* wrappers to create and manipulate new + // data structures. + // shape->NewNode( *tx1 ); face->NewNode( *shape ); - face->AddRefNode( *cp ); coordIdx->NewNode( *face ); - coordIdx->SetIndices( 3, &cidx[3] ); - SGNODE* face2 = face->GetRawPtr(); - // red + cp->NewNode( *face ); + np->NewNode( *face ); + // 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->SetSpecular( 1.0, 0.0, 0.0 ); material->SetDiffuse( 0.9, 0.0, 0.0 ); material->SetAmbient( 0.9 ); material->SetShininess( 0.3 ); + // // Shape3 + // shape->NewNode( *tx1 ); face->NewNode( *shape ); - face->AddRefNode( *cp ); coordIdx->NewNode( *face ); - coordIdx->SetIndices( 3, &cidx[6] ); - SGNODE* face3 = face->GetRawPtr(); - // green + cp->NewNode( *face ); + np->NewNode( *face ); + // 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->SetSpecular( 0.0, 1.0, 0.0 ); material->SetDiffuse( 0.0, 0.9, 0.0 ); material->SetAmbient( 0.9 ); material->SetShininess( 0.3 ); + // // Shape4 + // shape->NewNode( *tx1 ); face->NewNode( *shape ); - face->AddRefNode( *cp ); coordIdx->NewNode( *face ); - coordIdx->SetIndices( 3, &cidx[9] ); - SGNODE* face4 = face->GetRawPtr(); - // blue + cp->NewNode( *face ); + np->NewNode( *face ); + // 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->SetSpecular( 0.0, 0.0, 1.0 ); material->SetDiffuse( 0.0, 0.0, 0.9 ); material->SetAmbient( 0.9 ); 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 IFSG_TRANSFORM* tx2 = new IFSG_TRANSFORM( tx0->GetRawPtr() ); tx2->AddRefNode( *tx1 ); @@ -287,6 +309,7 @@ SCENEGRAPH* Load( char const* aFileName ) delete coordIdx; delete material; delete cp; + delete np; delete tx0; delete tx1; delete tx2; diff --git a/plugins/3d/idf/s3d_plugin_idf.cpp b/plugins/3d/idf/s3d_plugin_idf.cpp index bf097e9b1a..eb2180dcc8 100644 --- a/plugins/3d/idf/s3d_plugin_idf.cpp +++ b/plugins/3d/idf/s3d_plugin_idf.cpp @@ -258,10 +258,11 @@ SCENEGRAPH* Load( char const* aFileName ) vpcb.Tesselate( NULL ); std::vector< double > vertices; - std::vector< int > indices; + std::vector< int > idxPlane; + std::vector< int > idxSide; double thick = outline->GetThickness(); - if( !vpcb.Get3DTriangles( vertices, indices, thick, 0.0 ) ) + if( !vpcb.Get3DTriangles( vertices, idxPlane, idxSide, thick, 0.0 ) ) { #ifdef DEBUG std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; @@ -271,6 +272,15 @@ SCENEGRAPH* Load( char const* aFileName ) 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; size_t nvert = vertices.size() / 3; 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] ) ); // create the intermediate scenegraph - IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); - IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 ); - IFSG_FACESET* face = new IFSG_FACESET( *shape ); - IFSG_COORDS* cp = new IFSG_COORDS( *face ); + IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); // tx0 = top level Transform + 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 ); // this face shall represent the top and bottom planes + IFSG_COORDS* cp = new IFSG_COORDS( *face ); // coordinates for all faces cp->SetCoordsList( nvert, &vlist[0] ); - IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); - coordIdx->SetIndices( indices.size(), &indices[0] ); + IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); // coordinate indices for top and bottom planes only + 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 - std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; - std::cerr << " * [INFO] cannot calculate normals\n"; - #endif + p1 = vlist[*sI]; + cp->AddCoord( p1 ); + ++sI; + + 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(); // DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS diff --git a/utils/idftools/vrml_layer.cpp b/utils/idftools/vrml_layer.cpp index b3d28b8b5a..72172649c3 100644 --- a/utils/idftools/vrml_layer.cpp +++ b/utils/idftools/vrml_layer.cpp @@ -1793,10 +1793,12 @@ void VRML_LAYER::SetVertexOffsets( double aXoffset, double aYoffset ) 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(); - aIndexList.clear(); + aIndexPlane.clear(); + aIndexSide.clear(); if( ordmap.size() < 3 || outline.empty() ) 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 tend = triplets.end(); + std::vector< int > aIndexBot; + while( tbeg != tend ) { // top vertices - aIndexList.push_back( (int) tbeg->i1 ); - aIndexList.push_back( (int) tbeg->i2 ); - aIndexList.push_back( (int) tbeg->i3 ); + aIndexPlane.push_back( (int) tbeg->i1 ); + aIndexPlane.push_back( (int) tbeg->i2 ); + aIndexPlane.push_back( (int) tbeg->i3 ); // bottom vertices - aIndexList.push_back( (int) ( tbeg->i2 + vsize ) ); - aIndexList.push_back( (int) ( tbeg->i1 + vsize ) ); - aIndexList.push_back( (int) ( tbeg->i3 + vsize ) ); + aIndexBot.push_back( (int) ( tbeg->i2 + vsize ) ); + aIndexBot.push_back( (int) ( tbeg->i1 + vsize ) ); + aIndexBot.push_back( (int) ( tbeg->i3 + vsize ) ); ++tbeg; } + + aIndexPlane.insert( aIndexPlane.end(), aIndexBot.begin(), aIndexBot.end() ); } // compile indices for the walls joining top to bottom @@ -1902,23 +1908,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList, if( !holes_only ) { - aIndexList.push_back( curPoint ); - aIndexList.push_back( lastPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( curPoint ); + aIndexSide.push_back( lastPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( lastPoint ); - aIndexList.push_back( (int)( lastPoint + vsize ) ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); + aIndexSide.push_back( (int)( lastPoint + vsize ) ); } else { - aIndexList.push_back( curPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( lastPoint ); + aIndexSide.push_back( curPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( (int)( lastPoint + vsize ) ); - aIndexList.push_back( lastPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( (int)( lastPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); } lastPoint = curPoint; @@ -1933,23 +1939,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList, if( !holes_only ) { - aIndexList.push_back( curPoint ); - aIndexList.push_back( lastPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( curPoint ); + aIndexSide.push_back( lastPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( lastPoint ); - aIndexList.push_back( (int)( lastPoint + vsize ) ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); + aIndexSide.push_back( (int)( lastPoint + vsize ) ); } else { - aIndexList.push_back( curPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( lastPoint ); + aIndexSide.push_back( curPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); - aIndexList.push_back( (int)( curPoint + vsize ) ); - aIndexList.push_back( (int)( lastPoint + vsize ) ); - aIndexList.push_back( lastPoint ); + aIndexSide.push_back( (int)( curPoint + vsize ) ); + aIndexSide.push_back( (int)( lastPoint + vsize ) ); + aIndexSide.push_back( lastPoint ); } ++obeg; diff --git a/utils/idftools/vrml_layer.h b/utils/idftools/vrml_layer.h index 17a7d7d9fe..2b03fe35fa 100644 --- a/utils/idftools/vrml_layer.h +++ b/utils/idftools/vrml_layer.h @@ -463,12 +463,14 @@ public: * triangular vertices which may be used for rendering. * * @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 aBotZ is the bottom plane of the model */ 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 ); };