diff --git a/EgtExchange.rc b/EgtExchange.rc index 464971a..8165de4 100644 Binary files a/EgtExchange.rc and b/EgtExchange.rc differ diff --git a/ExcExecutor.cpp b/ExcExecutor.cpp index 50eb92d..a37807b 100644 --- a/ExcExecutor.cpp +++ b/ExcExecutor.cpp @@ -82,8 +82,8 @@ ExcExecutor::SetGeomDB( IGeomDB* pGdb) bool ExcExecutor::ExecuteImportStl( const string& sCmd2, const STRVECTOR& vsParams) { - // 2 parametri : nome del file e Id del gruppo - if ( vsParams.size() != 2) + // 2 o 3 parametri : nome del file, Id del gruppo[, ScaleFactor] + if ( vsParams.size() != 2 && vsParams.size() != 3) return false ; // eventuale conversione di token nel nome file string sFile = vsParams[0] ; @@ -92,6 +92,10 @@ ExcExecutor::ExecuteImportStl( const string& sCmd2, const STRVECTOR& vsParams) int nId = m_pParser->GetIdParam( vsParams[1]) ; if ( nId == CMD_ID_ERROR) return false ; + // gestisco ScaleFactor + double dScaleFactor = 1 ; + if ( vsParams.size() >= 3) + FromString( vsParams[2], dScaleFactor) ; // preparo l'importatore IImportStl* pImpStl = CreateImportStl() ; @@ -100,7 +104,7 @@ ExcExecutor::ExecuteImportStl( const string& sCmd2, const STRVECTOR& vsParams) return false ; } // eseguo l'importazione - bool bOk = pImpStl->Import( sFile, m_pGDB, nId) ; + bool bOk = pImpStl->Import( sFile, m_pGDB, nId, dScaleFactor) ; // cancello l'importatore delete pImpStl ; diff --git a/ImportStl.cpp b/ImportStl.cpp index 10934f8..45167cc 100644 --- a/ImportStl.cpp +++ b/ImportStl.cpp @@ -19,11 +19,15 @@ #include "/EgtDEv/Include/EGnScan.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgnStringConverter.h" +#include "/EgtDev/Include/EGkPointGrid3d.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" using namespace std ; +//---------------------------------------------------------------------------- +static const int GRID_NUM_BUCKETS = 50000 ; + //---------------------------------------------------------------------------- IImportStl* CreateImportStl( void) @@ -33,13 +37,35 @@ CreateImportStl( void) //---------------------------------------------------------------------------- bool -ImportStl::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup) +ImportStl::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor) { + // 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 ; + + // verifico il fattore di scala + if ( dScaleFactor < EPS_SMALL) { + LOG_ERROR( GetEExLogger(), "ImportStl : Error on ScaleFactor too small (minimum 0.001).") + return false ; + } + m_dScaleFactor = dScaleFactor ; + + // eseguo l'opportuna importazione switch ( StlType( sFile)) { case STL_ASCII : - return ImportASCII( sFile, pGDB, nIdGroup) ; + return ImportASCII( sFile) ; case STL_BINARY : - return ImportBinary( sFile, pGDB, nIdGroup) ; + return ImportBinary( sFile) ; default : return false ; } @@ -78,7 +104,7 @@ ImportStl::StlType( const std::string& sFile) //---------------------------------------------------------------------------- bool -ImportStl::ImportASCII( const string& sFile, IGeomDB* pGDB, int nIdGroup) +ImportStl::ImportASCII( const string& sFile) { // inizializzo lo scanner Scanner TheScanner ; @@ -87,20 +113,6 @@ ImportStl::ImportASCII( const string& sFile, IGeomDB* pGDB, int nIdGroup) 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 ; @@ -151,15 +163,15 @@ ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd) return false ; } - // Map dei vertici ( lexicographic -> usare epsilon piccoli) - CmpPnt comp( EPS_SMALL) ; - PntIntMap MapVert( comp) ; + // Grid dei vertici + PointGrid3d VertGrid ; + VertGrid.Init( GRID_NUM_BUCKETS) ; // ciclo di lettura dei triangoli bool bOk = true ; bool bTEnd = false ; do { - if ( ! LoadTriangle( TheScanner, Get( pSTM), MapVert, bTEnd)) { + if ( ! LoadTriangle( TheScanner, Get( pSTM), VertGrid, bTEnd)) { bOk = false ; string sOut = "ImportStl : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) @@ -195,7 +207,7 @@ ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd) //---------------------------------------------------------------------------- bool -ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PntIntMap& MapVert, bool& bEnd) +ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PointGrid3d& VertGrid, bool& bEnd) { string sLine ; STRVECTOR vsParams ; @@ -230,7 +242,6 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PntIntMap& Map // ciclo sui tre vertici int nIdV[3] ; - PntIntMap::iterator Iter ; for ( int i = 0 ; i < 3 ; ++ i) { // recupero una linea if ( ! TheScanner.GetLine( sLine)) @@ -249,16 +260,18 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PntIntMap& Map ! FromString( vsParams[2], ptP.y) || ! FromString( vsParams[3], ptP.z)) return false ; + // scalo il vertice + ptP *= m_dScaleFactor ; // verifico se vertice già presente - Iter = MapVert.find( ptP) ; - if ( Iter == MapVert.end()) { + int nId ; + if ( ! VertGrid.Find( ptP, 2 * EPS_SMALL, nId)) { // aggiungo il vertice if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == SVT_NULL) return false ; - MapVert[ptP] = nIdV[i] ; + VertGrid.InsertPoint( ptP, nIdV[i]) ; } else - nIdV[i] = Iter->second ; + nIdV[i] = nId ; } // se i vertici sono tutti diversi tra loro, inserisco il triangolo @@ -297,7 +310,7 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PntIntMap& Map //---------------------------------------------------------------------------- bool -ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) +ImportStl::ImportBinary( const string& sFile) { // apertura del file di ingresso ifstream InFile ; @@ -305,20 +318,6 @@ ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) if ( InFile.fail()) 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 ; - // lettura dei primi ottanta byte (commento da scartare) const int LEN_REM = 80 ; char cRem[LEN_REM] ; @@ -344,9 +343,9 @@ ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) return false ; } - // Map dei vertici ( lexicographic -> usare epsilon piccoli) - CmpPnt comp( EPS_SMALL) ; - PntIntMap MapVert( comp) ; + // Grid dei vertici + PointGrid3d VertGrid ; + VertGrid.Init( GRID_NUM_BUCKETS) ; // lettura dei triangoli for ( int j = 0 ; j < uTria.i ; ++ j) { @@ -358,7 +357,6 @@ ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) return false ; // ciclo sui tre vertici int nIdV[3] ; - PntIntMap::iterator Iter ; for ( int i = 0 ; i < 3 ; ++ i) { const int LEN_3F = 12 ; union { float f[3]; char c[LEN_3F]; } ufP ; @@ -366,16 +364,18 @@ ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) if ( InFile.gcount() != LEN_3F) return false ; Point3d ptP( ufP.f[0], ufP.f[1], ufP.f[2]) ; + // scalo il vertice + ptP *= m_dScaleFactor ; // verifico se vertice già presente - Iter = MapVert.find( ptP) ; - if ( Iter == MapVert.end()) { + int nId ; + if ( ! VertGrid.Find( ptP, 2 * EPS_SMALL, nId)) { // aggiungo il vertice if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == SVT_NULL) return false ; - MapVert[ptP] = nIdV[i] ; + VertGrid.InsertPoint( ptP, nIdV[i]) ; } else - nIdV[i] = Iter->second ; + nIdV[i] = nId ; } // se i vertici sono tutti diversi tra loro, inserisco il triangolo diff --git a/ImportStl.h b/ImportStl.h index b347f33..b637c77 100644 --- a/ImportStl.h +++ b/ImportStl.h @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- -// File : ImportStl.h Data : 04.04.14 Versione : 1.5d1 +// File : ImportStl.h Data : 16.05.14 Versione : 1.5e3 // Contenuto : Dichiarazione della classe ImportStl. // // @@ -15,10 +15,10 @@ #include "/EgtDev/Include/EExImportStl.h" #include "/EgtDev/Include/EgkPoint3d.h" -#include class Scanner ; class ISurfTriMesh ; +class PointGrid3d ; //---------------------------------------------------------------------------- @@ -26,37 +26,14 @@ class ISurfTriMesh ; class ImportStl : public IImportStl { public : - virtual bool Import( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; - - private : - class CmpPnt - { - public : - CmpPnt( double dEps = EPS_SMALL) : m_dEps( dEps) - {} - bool operator()( const Point3d& ptP0, const Point3d& ptP1) const - { - if ( fabs( ptP0.x - ptP1.x) <= m_dEps) { - if ( fabs( ptP0.y - ptP1.y) <= m_dEps) { - return ( ptP0.z < ptP1.z - m_dEps) ; - } - else - return ( ptP0.y < ptP1.y - m_dEps) ; - } - else - return ( ptP0.x < ptP1.x - m_dEps) ; - } - private : - double m_dEps ; - } ; - typedef std::map< Point3d, int, CmpPnt> PntIntMap ; + virtual bool Import( const std::string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor = 1) ; private : int StlType( const std::string& sFile) ; - bool ImportASCII( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; + bool ImportASCII( const std::string& sFile) ; bool LoadSolid( Scanner& TheScanner, bool& bEnd) ; - bool LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PntIntMap& MapVert, bool& bEnd) ; - bool ImportBinary( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; + bool LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, PointGrid3d& VertGrid, bool& bEnd) ; + bool ImportBinary( const std::string& sFile) ; private : enum { STL_ERROR = 0, STL_ASCII = 1, STL_BINARY = 2 } ; @@ -64,4 +41,5 @@ class ImportStl : public IImportStl private : IGeomDB* m_pGDB ; int m_nIdGroup ; + double m_dScaleFactor ; } ;