From b28ee2f442aba628c9fea108f90a726be1cf729f Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 7 Apr 2014 07:01:40 +0000 Subject: [PATCH] EgtExchange 1.5d2 : - aggiunto accorpamento vertici - aggiunta importazione STL binari. --- EgtExchange.rc | Bin 11478 -> 11478 bytes ExcExecutor.cpp | 5 +- ImportStl.cpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++-- ImportStl.h | 39 ++++++++++- 4 files changed, 210 insertions(+), 12 deletions(-) diff --git a/EgtExchange.rc b/EgtExchange.rc index cf0627603821f0e698173c438efedb44bd72f312..a49b26fcf16335f0767fd22b3cda1c5d6f973bc5 100644 GIT binary patch delta 102 zcmcZ>c`b6oH#SD2&4O|VnIc`b6oH#SDY&4O|VnIImport( vsParams[0], m_pGDB, nId)) - return false ; + bool bOk = pImpStl->Import( vsParams[0], m_pGDB, nId) ; // cancello l'importatore delete pImpStl ; - return true ; + return bOk ; } diff --git a/ImportStl.cpp b/ImportStl.cpp index 3dfb606..6555720 100644 --- a/ImportStl.cpp +++ b/ImportStl.cpp @@ -18,6 +18,7 @@ #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDEv/Include/EGnScan.h" #include "/EgtDev/Include/EgnStringUtils.h" +#include "/EgtDev/Include/EgnStringConverter.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" @@ -33,6 +34,47 @@ CreateImportStl( void) //---------------------------------------------------------------------------- bool ImportStl::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup) +{ + switch ( StlType( sFile)) { + case STL_ASCII : + return ImportASCII( sFile, pGDB, nIdGroup) ; + case STL_BINARY : + return ImportBinary( sFile, pGDB, nIdGroup) ; + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +int +ImportStl::StlType( const std::string& sFile) +{ + // apertura del file di ingresso + ifstream InFile ; + InFile.open( stringtoW( sFile), ios::in | ios::binary) ; + if ( InFile.fail()) + return STL_ERROR ; + + // lettura dei primi ottanta byte + char cBuff[81] ; + InFile.read( cBuff, 80) ; + cBuff[InFile.gcount()] = '\0' ; + + // chiusura del file + InFile.close() ; + + // verifico se iniziano con "solid" + string sBuff = cBuff ; + size_t nPos = sBuff.find( "solid") ; + if ( nPos != string::npos && nPos < 10) + return STL_ASCII ; + else + return STL_BINARY ; +} + +//---------------------------------------------------------------------------- +bool +ImportStl::ImportASCII( const string& sFile, IGeomDB* pGDB, int nIdGroup) { // inizializzo lo scanner Scanner TheScanner ; @@ -105,6 +147,9 @@ ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd) return false ; } + // pulisco Map dei vertici + m_MapVert.clear() ; + // ciclo di lettura dei triangoli bool bOk = true ; bool bTEnd = false ; @@ -140,7 +185,7 @@ ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd) m_pGDB->SetName( nIdNew, sName) ; bEnd = false ; - return true ; + return ( nIdNew != GDB_ID_NULL) ; } //---------------------------------------------------------------------------- @@ -180,6 +225,7 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd) // ciclo sui tre vertici int nIdV[3] ; + PntIntMap::iterator Iter ; for ( int i = 0 ; i < 3 ; ++ i) { // recupero una linea if ( ! TheScanner.GetLine( sLine)) @@ -198,14 +244,23 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd) ! FromString( vsParams[2], ptP.y) || ! FromString( vsParams[3], ptP.z)) return false ; - // aggiungo il vertice - if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == -1) - return false ; + // verifico se vertice già presente + Iter = m_MapVert.find( ptP) ; + if ( Iter == m_MapVert.end()) { + // aggiungo il vertice + if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == -1) + return false ; + m_MapVert[ptP] = nIdV[i] ; + } + else + nIdV[i] = Iter->second ; } - // inserisco il triangolo - if( pSTM->AddTriangle( nIdV) == -1) - return false ; + // se i vertici sono tutti diversi tra loro, inserisco il triangolo + if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) { + if ( pSTM->AddTriangle( nIdV) == -1) + return false ; + } // nuova linea if ( ! TheScanner.GetLine( sLine)) @@ -234,3 +289,112 @@ ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd) bEnd = false ; return true ; } + +//---------------------------------------------------------------------------- +bool +ImportStl::ImportBinary( const string& sFile, IGeomDB* pGDB, int nIdGroup) +{ + // apertura del file di ingresso + ifstream InFile ; + InFile.open( stringtoW( sFile), ios::in | ios::binary) ; + 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] ; + InFile.read( cRem, LEN_REM) ; + if ( InFile.gcount() != LEN_REM) + return false ; + + // lettura del numero di triangoli + const int LEN_INT = 4 ; + union { int i; char c[LEN_INT]; } uTria ; + InFile.read( uTria.c, LEN_INT) ; + if ( InFile.gcount() != LEN_INT) + return false ; + + // 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 ; + } + + // pulisco Map dei vertici + m_MapVert.clear() ; + + // lettura dei triangoli + for ( int j = 0 ; j < uTria.i ; ++ j) { + // salto i 3 float per la normale + const int LEN_NRM = 12 ; + char cNorm[LEN_NRM] ; + InFile.read( cNorm, LEN_NRM) ; + if ( InFile.gcount() != LEN_NRM) + 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 ; + InFile.read( ufP.c, LEN_3F) ; + if ( InFile.gcount() != LEN_3F) + return false ; + Point3d ptP( ufP.f[0], ufP.f[1], ufP.f[2]) ; + // verifico se vertice già presente + Iter = m_MapVert.find( ptP) ; + if ( Iter == m_MapVert.end()) { + // aggiungo il vertice + if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == -1) + return false ; + m_MapVert[ptP] = nIdV[i] ; + } + else + nIdV[i] = Iter->second ; + } + + // se i vertici sono tutti diversi tra loro, inserisco il triangolo + if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) { + if ( pSTM->AddTriangle( nIdV) == -1) + return false ; + } + // salto 2 byte + const int LEN_SKI = 2 ; + char cSkip[LEN_SKI] ; + InFile.read( cSkip, LEN_SKI) ; + if ( InFile.gcount() != LEN_SKI) + 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)) ; + + // chiusura del file + InFile.close() ; + + return ( nIdNew != GDB_ID_NULL) ; +} \ No newline at end of file diff --git a/ImportStl.h b/ImportStl.h index f48f92d..41895dc 100644 --- a/ImportStl.h +++ b/ImportStl.h @@ -14,10 +14,35 @@ #pragma once #include "/EgtDev/Include/EExImportStl.h" +#include "/EgtDev/Include/EgkPoint3d.h" +#include class Scanner ; class ISurfTriMesh ; +//---------------------------------------------------------------------------- +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 ; +} ; + //---------------------------------------------------------------------------- class ImportStl : public IImportStl { @@ -25,10 +50,20 @@ class ImportStl : public IImportStl virtual bool Import( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; private : + int StlType( const std::string& sFile) ; + bool ImportASCII( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; bool LoadSolid( Scanner& TheScanner, bool& bEnd) ; bool LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd) ; + bool ImportBinary( const std::string& sFile, IGeomDB* pGDB, int nIdGroup) ; private : - IGeomDB* m_pGDB ; - int m_nIdGroup ; + enum { STL_ERROR = 0, STL_ASCII = 1, STL_BINARY = 2 } ; + + private : + typedef std::map< Point3d, int, CmpPnt> PntIntMap ; + + private : + IGeomDB* m_pGDB ; + int m_nIdGroup ; + PntIntMap m_MapVert ; } ;