//---------------------------------------------------------------------------- // EgalTech 2024-2024 //---------------------------------------------------------------------------- // File : ImportOff.cpp Data : 28.11.24 Versione : 2.6k2 // Contenuto : Implementazione della classe per l'importazione di OFF. // // // // Modifiche : 28.11.24 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ImportOff.h" #include "DllMain.h" #include "/EgtDev/Include/EExDllMain.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- IImportOff* CreateImportOff( void) { // verifico la chiave e le opzioni if ( ! VerifyKey( KEYOPT_EEX_INPBASE)) return nullptr ; // creo l'oggetto return static_cast ( new( nothrow) ImportOff) ; } //---------------------------------------------------------------------------- bool ImportOff::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor) { // verifico il DB geometrico if ( pGDB == nullptr) { LOG_ERROR( GetEExLogger(), "ImportOff : Error on GeomDB") return false ; } m_pGDB = pGDB ; // verifico l'Id di gruppo if ( ! m_pGDB->ExistsObj( nIdGroup)) { LOG_ERROR( GetEExLogger(), "ImportOff : Error on IdGroup") return false ; } m_nIdGroup = nIdGroup ; // verifico il fattore di scala if ( dScaleFactor < EPS_SMALL) { LOG_ERROR( GetEExLogger(), "ImportOff : Error on ScaleFactor too small (minimum 0.001).") return false ; } m_dScaleFactor = dScaleFactor ; // inizializzo lo scanner if ( ! m_theScanner.Init( sFile, "#")) { LOG_ERROR( GetEExLogger(), "ImportOff : Error on Init") return false ; } // lettura intestazione if ( ! ReadData()) { string sOut = " ImportOff : Error in ReadData on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } return true ; } //---------------------------------------------------------------------------- bool ImportOff::ReadData( void) { string sLine ; // Intestazione opzionale OFF if ( ! m_theScanner.GetLine( sLine)) return false ; bool bOFF = ( sLine.find( "OFF") != string::npos) ; // Numero di vertici, di facce e di spigoli (ignorato) if ( bOFF && ! m_theScanner.GetLine( sLine)) return false ; STRVECTOR vsTok ; Tokenize( sLine, " ", vsTok) ; if ( vsTok.size() < 3) return false ; int nVerts = 0, nFaces = 0 ; if ( ! FromString( vsTok[0], nVerts) || nVerts <= 0 || ! FromString( vsTok[1], nFaces) || nFaces <= 0) return false ; // Vettore dei vertici PNTVECTOR vVert( nVerts) ; // lettura dei vertici for ( int i = 0 ; i < nVerts ; ++ i) { if ( ! m_theScanner.GetLine( sLine)) return false ; STRVECTOR vsTok ; Tokenize( sLine, " ", vsTok) ; if ( vsTok.size() < 3) return false ; if ( ! FromString( vsTok[0], vVert[i].x) || ! FromString( vsTok[1],vVert[i].y) || ! FromString( vsTok[2], vVert[i].z)) return false ; vVert[i] *= m_dScaleFactor ; } // Costruttore di trimesh da insieme disordinato di triangoli StmFromTriangleSoup StmFts ; if ( ! StmFts.Start()) return false ; // lettura delle facce int nBadFaces = 0 ; for ( int i = 0 ; i < nFaces ; ++ i) { if ( ! m_theScanner.GetLine( sLine)) return false ; STRVECTOR vsTok ; Tokenize( sLine, " ", vsTok) ; if ( vsTok.empty()) return false ; int nFVs = 0 ; if ( ! FromString( vsTok[0], nFVs) || int( vsTok.size()) < nFVs + 1) return false ; // se triangolo if ( nFVs == 3) { Triangle3d Tria ; for ( int j = 0 ; j < 3 ; ++ j) { int nV = -1 ; if ( ! FromString( vsTok[j+1], nV) || nV < 0 || nV >= nVerts) return false ; Tria.SetP( j, vVert[nV]) ; } if ( Tria.Validate( true)) { if ( ! StmFts.AddTriangle( Tria)) return false ; } else ++ nBadFaces ; } // se quadrilatero else if ( nFVs == 4) { Triangle3d TriaA, TriaB ; for ( int j = 0 ; j < 4 ; ++ j) { int nV = -1 ; if ( ! FromString( vsTok[j+1], nV) || nV < 0 || nV >= nVerts) return false ; if ( j != 3) TriaA.SetP( j, vVert[nV]) ; if ( j != 1) TriaB.SetP( ( j == 0 ? j : j - 1), vVert[nV]) ; } if ( TriaA.Validate( true)) { if ( ! StmFts.AddTriangle( TriaA)) return false ; } else ++ nBadFaces ; if ( TriaB.Validate( true)) { if ( ! StmFts.AddTriangle( TriaB)) return false ; } else ++ nBadFaces ; } // altrimenti poligono generico else { PolyLine PL ; for ( int j = 0 ; j < nFVs ; ++ j) { int nV = -1 ; if ( ! FromString( vsTok[j+1], nV) || nV < 0 || nV >= nVerts) return false ; PL.AddUPoint( j, vVert[nV]) ; } PL.Close() ; PL.FlattenInAutoPlane( 1.) ; PtrOwner pStm( CreateSurfTriMesh()) ; if ( ! IsNull( pStm) && pStm->CreateByFlatContour( PL)) { if ( ! StmFts.AddSurfTriMesh( *pStm)) return false ; } else ++ nBadFaces ; } } if ( nBadFaces > 0) { string sOut = " ImportOff : found " + ToString( nBadFaces) + " bad faces" ; LOG_ERROR( GetEExLogger(), sOut.c_str()) } // Valido la superficie e calcolo le adiacenze if ( ! StmFts.End()) return false ; // inserisco l'oggetto nel DB geometrico PtrOwner pSTM( StmFts.GetSurf()) ; int nIdNew = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nIdGroup, Release( pSTM)) ; if ( nIdNew == GDB_ID_NULL) return false ; return true ; }