//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : ImportStl.cpp Data : 04.04.14 Versione : 1.5d1 // Contenuto : Implementazione della classe per l'importazione di STL. // // // // Modifiche : 04.04.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ImportStl.h" #include "DllMain.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDEv/Include/EGnScan.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" using namespace std ; //---------------------------------------------------------------------------- IImportStl* CreateImportStl( void) { return static_cast ( new(nothrow) ImportStl) ; } //---------------------------------------------------------------------------- bool ImportStl::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup) { // inizializzo lo scanner Scanner TheScanner ; if ( ! TheScanner.Init( sFile)) { LOG_ERROR( GetEExLogger(), "ImportStl : Error on Init") return false ; } // verifico il DB geometrico if ( pGDB == nullptr) { LOG_ERROR( GetEExLogger(), "ImportStl : Error on GeomDB") return false ; } m_pGDB = pGDB ; // verifico l'Id di gruppo if ( ! m_pGDB->ExistsObj( nIdGroup)) { LOG_ERROR( GetEExLogger(), "ImportStl : Error on IdGroup") return false ; } m_nIdGroup = nIdGroup ; // ciclo di lettura degli oggetti bool bOk = true ; bool bEnd = false ; do { if ( ! LoadSolid( TheScanner, bEnd)) { bOk = false ; string sOut = "ImportStl : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) } } while ( bOk && ! bEnd) ; return bOk ; } //---------------------------------------------------------------------------- bool ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd) { string sLine ; STRVECTOR vsParams ; // recupero la prima linea if ( ! TheScanner.GetLine( sLine)) { bEnd = true ; return true ; } // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 1 parametro if ( vsParams.size() < 1) return false ; // deve essere la parola chiave "solid" if ( vsParams[0] != "solid") return false ; // se c'è un secondo parametro è il nome string sName ; if ( vsParams.size() >= 2) sName = vsParams[1] ; // preparo l'oggetto TriMesh PtrOwner pSTM( CreateSurfTriMesh()) ; if ( ! IsValid( pSTM)) { LOG_ERROR( GetEExLogger(), "ImportStl : Error allocating SurfTriMesh") return false ; } if ( ! pSTM->Init( 3, 1)) { LOG_ERROR( GetEExLogger(), "ImportStl : Error initialising SurfTriMesh") return false ; } // ciclo di lettura dei triangoli bool bOk = true ; bool bTEnd = false ; do { if ( ! LoadTriangle( TheScanner, Get( pSTM), bTEnd)) { bOk = false ; string sOut = "ImportStl : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) } } while ( bOk && ! bTEnd) ; // recupero la linea di terminazione dell'oggetto if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 1 parametro if ( vsParams.size() < 1) return false ; // deve essere la parola chiave "endsolid" oppure "end" "solid" if ( vsParams[0] != "endsolid" && vsParams[0] != "end") return false ; // valido la superficie e calcolo le adiacenze if ( ! pSTM->AdjustTopology()) { LOG_ERROR( GetEExLogger(), "ImportStl : Error adjusting topology in SurfTriMesh") return false ; } // inserisco l'oggetto nel DB geometrico int nIdNew = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nIdGroup, Release( pSTM)) ; // se previsto il nome, lo assegno if ( ! sName.empty()) m_pGDB->SetName( nIdNew, sName) ; bEnd = false ; return true ; } //---------------------------------------------------------------------------- bool ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd) { string sLine ; STRVECTOR vsParams ; // recupero la prima linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 1 parametro if ( vsParams.size() < 1) return false ; // deve essere la parola chiave "facet" if ( vsParams[0] != "facet") { TheScanner.UngetLine( sLine) ; bEnd = true ; return true ; } // ignoro il resto // recupero la seconda linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 2 parametri if ( vsParams.size() < 2) return false ; // devono essere le parole chiave "outer" e "loop" if ( vsParams[0] != "outer" || vsParams[1] != "loop") return false ; // ciclo sui tre vertici int nIdV[3] ; for ( int i = 0 ; i < 3 ; ++ i) { // recupero una linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 4 parametri if ( vsParams.size() < 4) return false ; // parola chiave "vertex" if ( vsParams[0] != "vertex") return false ; // tre coordinate del vertice Point3d ptP ; if ( ! FromString( vsParams[1], ptP.x) || ! FromString( vsParams[2], ptP.y) || ! FromString( vsParams[3], ptP.z)) return false ; // aggiungo il vertice if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == -1) return false ; } // inserisco il triangolo if( pSTM->AddTriangle( nIdV) == -1) return false ; // nuova linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 1 parametro if ( vsParams.size() < 1) return false ; // parola chiave "endloop" if ( vsParams[0] != "endloop") return false ; // nuova linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, " ", vsParams) ; // almeno 1 parametro if ( vsParams.size() < 1) return false ; // parola chiave "endfacet" if ( vsParams[0] != "endfacet") return false ; bEnd = false ; return true ; }