// writes out the vertex list; // 'z' is the Z coordinate of every point bool VRML_LAYER::WriteVertices( double z, FILE* fp ) { if( !fp ) { error = "WriteVertices(): invalid file pointer"; return false; } if( ordmap.size() < 3 ) { error = "WriteVertices(): not enough vertices"; return false; } int i, j; VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes ); if( !vp ) return false; std::string strx, stry, strz; FormatDoublet( vp->x, vp->y, 6, strx, stry ); FormatSinglet( z, 6, strz ); fprintf( fp, "%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); if( !vp ) return false; FormatDoublet( vp->x, vp->y, 6, strx, stry ); if( i & 1 ) fprintf( fp, ", %s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); else fprintf( fp, ",\n%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); } return true; }
// writes out the vertex list for a planar feature bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPrecision ) { if( ordmap.size() < 3 ) { error = "WriteVertices(): not enough vertices"; return false; } if( aPrecision < 4 ) aPrecision = 4; int i, j; VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes ); if( !vp ) return false; std::string strx, stry, strz; FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); FormatSinglet( aZcoord, aPrecision, strz ); aOutFile << strx << " " << stry << " " << strz; for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); if( !vp ) return false; FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); if( i & 1 ) aOutFile << ", " << strx << " " << stry << " " << strz; else aOutFile << ",\n" << strx << " " << stry << " " << strz; } return !aOutFile.fail(); }
bool VRML_LAYER::pushOutline( VRML_LAYER* holes ) { // traverse the outline list to push all used vertices if( outline.size() < 1 ) { error = "pushOutline() failed: no vertices to push"; return false; } std::list<std::list<int>*>::const_iterator obeg = outline.begin(); std::list<std::list<int>*>::const_iterator oend = outline.end(); int nc = 0; // number of contours pushed int pi; std::list<int>::const_iterator begin; std::list<int>::const_iterator end; GLdouble pt[3]; VERTEX_3D* vp; while( obeg != oend ) { if( (*obeg)->size() < 3 ) { ++obeg; continue; } gluTessBeginContour( tess ); begin = (*obeg)->begin(); end = (*obeg)->end(); while( begin != end ) { pi = *begin; if( pi < 0 || (unsigned int) pi > ordmap.size() ) { gluTessEndContour( tess ); error = "pushOutline():BUG: *outline.begin() is not a valid index to ordmap"; return false; } // retrieve the actual index pi = ordmap[pi]; vp = getVertexByIndex( pi, holes ); if( !vp ) { gluTessEndContour( tess ); error = "pushOutline():: BUG: ordmap[n] is not a valid index to vertices[]"; return false; } pt[0] = vp->x; pt[1] = vp->y; pt[2] = 0.0; gluTessVertex( tess, pt, vp ); ++begin; } gluTessEndContour( tess ); ++obeg; ++nc; } if( !nc ) { error = "pushOutline():: no valid contours available"; return false; } return true; }
bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList, std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide, double aTopZ, double aBotZ ) { aVertexList.clear(); aIndexPlane.clear(); aIndexSide.clear(); if( ordmap.size() < 3 || outline.empty() ) return false; if( aTopZ <= aBotZ ) { double tmp = aBotZ; aBotZ = aTopZ; aTopZ = tmp; } VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes ); if( !vp ) return false; size_t i; size_t vsize = ordmap.size(); // top vertices for( i = 0; i < vsize; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); if( !vp ) { aVertexList.clear(); return false; } aVertexList.push_back( vp->x ); aVertexList.push_back( vp->y ); aVertexList.push_back( aTopZ ); } // bottom vertices for( i = 0; i < vsize; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); aVertexList.push_back( vp->x ); aVertexList.push_back( vp->y ); aVertexList.push_back( aBotZ ); } // create the index lists .. it is difficult to estimate the list size // a priori so instead we use a vector to help bool holes_only = triplets.empty(); if( !holes_only ) { // go through the triplet list and write out the indices based on order 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 aIndexPlane.push_back( (int) tbeg->i1 ); aIndexPlane.push_back( (int) tbeg->i2 ); aIndexPlane.push_back( (int) tbeg->i3 ); // bottom vertices 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 int lastPoint; int curPoint; int curContour = 0; std::list< std::list< int >* >::const_iterator obeg = outline.begin(); std::list< std::list< int >* >::const_iterator oend = outline.end(); std::list< int >* cp; std::list< int >::const_iterator cbeg; std::list< int >::const_iterator cend; i = 2; while( obeg != oend ) { cp = *obeg; if( cp->size() < 3 ) { ++obeg; ++curContour; continue; } cbeg = cp->begin(); cend = cp->end(); lastPoint = *(cbeg++); while( cbeg != cend ) { curPoint = *(cbeg++); if( !holes_only ) { aIndexSide.push_back( curPoint ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( lastPoint + vsize ) ); } else { aIndexSide.push_back( curPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( lastPoint ); } lastPoint = curPoint; } // check if the loop needs to be closed cbeg = cp->begin(); cend = --cp->end(); curPoint = *(cbeg); lastPoint = *(cend); if( !holes_only ) { aIndexSide.push_back( curPoint ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( lastPoint + vsize ) ); } else { aIndexSide.push_back( curPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( lastPoint ); aIndexSide.push_back( (int)( curPoint + vsize ) ); aIndexSide.push_back( (int)( lastPoint + vsize ) ); aIndexSide.push_back( lastPoint ); } ++obeg; ++curContour; } return true; }
// writes out the index list for a 3D feature bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile, bool aIncludePlatedHoles ) { if( outline.empty() ) { error = "WriteIndices(): no outline available"; return false; } char mark; bool holes_only = triplets.empty(); int i = 1; int idx2 = ordmap.size(); // index to the bottom vertices if( !holes_only ) { mark = ','; // go through the triplet list and write out the indices based on order std::list<TRIPLET_3D>::const_iterator tbeg = triplets.begin(); std::list<TRIPLET_3D>::const_iterator tend = triplets.end(); // print out the top vertices aOutFile << tbeg->i1 << ", " << tbeg->i2 << ", " << tbeg->i3 << ", -1"; ++tbeg; while( tbeg != tend ) { if( (i++ & 7) == 4 ) { i = 1; aOutFile << ",\n" << tbeg->i1 << ", " << tbeg->i2 << ", " << tbeg->i3 << ", -1"; } else { aOutFile << ", " << tbeg->i1 << ", " << tbeg->i2 << ", " << tbeg->i3 << ", -1"; } ++tbeg; } // print out the bottom vertices tbeg = triplets.begin(); while( tbeg != tend ) { if( (i++ & 7) == 4 ) { i = 1; aOutFile << ",\n" << (tbeg->i2 + idx2) << ", " << (tbeg->i1 + idx2) << ", " << (tbeg->i3 + idx2) << ", -1"; } else { aOutFile << ", " << (tbeg->i2 + idx2) << ", " << (tbeg->i1 + idx2) << ", " << (tbeg->i3 + idx2) << ", -1"; } ++tbeg; } } else mark = ' '; // print out indices for the walls joining top to bottom int lastPoint; int curPoint; int curContour = 0; std::list<std::list<int>*>::const_iterator obeg = outline.begin(); std::list<std::list<int>*>::const_iterator oend = outline.end(); std::list<int>* cp; std::list<int>::const_iterator cbeg; std::list<int>::const_iterator cend; i = 2; while( obeg != oend ) { cp = *obeg; if( cp->size() < 3 ) { ++obeg; ++curContour; continue; } cbeg = cp->begin(); cend = cp->end(); lastPoint = *(cbeg++); // skip all PTH vertices which are not in a solid outline if( !aIncludePlatedHoles && !solid[curContour] && getVertexByIndex( ordmap[lastPoint], pholes )->pth ) { ++obeg; ++curContour; continue; } while( cbeg != cend ) { curPoint = *(cbeg++); if( !holes_only ) { if( (i++ & 3) == 2 ) { i = 1; aOutFile << mark << "\n" << curPoint << ", " << lastPoint << ", " << curPoint + idx2; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1"; } else { aOutFile << mark << " " << curPoint << ", " << lastPoint << ", " << curPoint + idx2; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1"; } } else { if( (i++ & 3) == 2 ) { i = 1; aOutFile << mark << "\n" << curPoint << ", " << curPoint + idx2 << ", " << lastPoint; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1"; } else { aOutFile << mark << " " << curPoint << ", " << curPoint + idx2 << ", " << lastPoint; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1"; } } mark = ','; lastPoint = curPoint; } // check if the loop needs to be closed cbeg = cp->begin(); cend = --cp->end(); curPoint = *(cbeg); lastPoint = *(cend); if( !holes_only ) { if( (i++ & 3) == 2 ) { aOutFile << ",\n" << curPoint << ", " << lastPoint << ", " << curPoint + idx2; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1"; } else { aOutFile << ", " << curPoint << ", " << lastPoint << ", " << curPoint + idx2; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1"; } } else { if( (i++ & 3) == 2 ) { aOutFile << ",\n" << curPoint << ", " << curPoint + idx2 << ", " << lastPoint; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1"; } else { aOutFile << ", " << curPoint << ", " << curPoint + idx2 << ", " << lastPoint; aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1"; } } ++obeg; ++curContour; } return !aOutFile.fail(); }
// writes out the vertex list for a 3D feature; top and bottom are the // Z values for the top and bottom; top must be > bottom bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ, std::ofstream& aOutFile, int aPrecision ) { if( ordmap.size() < 3 ) { error = "Write3DVertices(): insufficient vertices"; return false; } if( aPrecision < 4 ) aPrecision = 4; if( aTopZ <= aBottomZ ) { error = "Write3DVertices(): top <= bottom"; return false; } int i, j; VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes ); if( !vp ) return false; std::string strx, stry, strz; FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); FormatSinglet( aTopZ, aPrecision, strz ); aOutFile << strx << " " << stry << " " << strz; for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); if( !vp ) return false; FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); if( i & 1 ) aOutFile << ", " << strx << " " << stry << " " << strz; else aOutFile << ",\n" << strx << " " << stry << " " << strz; } // repeat for the bottom layer vp = getVertexByIndex( ordmap[0], pholes ); FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); FormatSinglet( aBottomZ, aPrecision, strz ); bool endl; if( i & 1 ) { aOutFile << ", " << strx << " " << stry << " " << strz; endl = false; } else { aOutFile << ",\n" << strx << " " << stry << " " << strz; endl = true; } for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); FormatDoublet( vp->x + offsetX, vp->y + offsetY, aPrecision, strx, stry ); if( endl ) { aOutFile << ", " << strx << " " << stry << " " << strz; endl = false; } else { aOutFile << ",\n" << strx << " " << stry << " " << strz; endl = true; } } return !aOutFile.fail(); }
// writes out the vertex list for a 3D feature; top and bottom are the // Z values for the top and bottom; top must be > bottom bool VRML_LAYER::Write3DVertices( double top, double bottom, FILE* fp ) { if( !fp ) { error = "Write3DVertices(): NULL file pointer"; return false; } if( ordmap.size() < 3 ) { error = "Write3DVertices(): insufficient vertices"; return false; } if( top <= bottom ) { error = "Write3DVertices(): top <= bottom"; return false; } int i, j; VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes ); if( !vp ) return false; std::string strx, stry, strz; FormatDoublet( vp->x, vp->y, 6, strx, stry ); FormatSinglet( top, 6, strz ); fprintf( fp, "%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); if( !vp ) return false; FormatDoublet( vp->x, vp->y, 6, strx, stry ); if( i & 1 ) fprintf( fp, ", %s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); else fprintf( fp, ",\n%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); } // repeat for the bottom layer vp = getVertexByIndex( ordmap[0], pholes ); FormatDoublet( vp->x, vp->y, 6, strx, stry ); FormatSinglet( bottom, 6, strz ); bool endl; if( i & 1 ) { fprintf( fp, ", %s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); endl = false; } else { fprintf( fp, ",\n%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); endl = true; } for( i = 1, j = ordmap.size(); i < j; ++i ) { vp = getVertexByIndex( ordmap[i], pholes ); FormatDoublet( vp->x, vp->y, 6, strx, stry ); if( endl ) { fprintf( fp, ", %s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); endl = false; } else { fprintf( fp, ",\n%s %s %s", strx.c_str(), stry.c_str(), strz.c_str() ); endl = true; } } return true; }