//---------------------------------------------------------------------------- // EgalTech 2025-2025 //---------------------------------------------------------------------------- // File : ImportPLY.cpp Data : 28.02.25 Versione : 2.7b2 // Contenuto : Implementazione della classe per l'importazione di PLY. // // // // Modifiche : 28.02.25 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ImportPly.h" #include "DllMain.h" #include "/EgtDev/Include/EExDllMain.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- IImportPly* CreateImportPly( void) { // verifico la chiave e le opzioni if ( ! VerifyKey( KEYOPT_EEX_INPBASE)) return nullptr ; // creo l'oggetto return static_cast ( new( nothrow) ImportPly) ; } //---------------------------------------------------------------------------- bool ImportPly::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor) { // verifico il DB geometrico if ( pGDB == nullptr) { LOG_ERROR( GetEExLogger(), "ImportPly : Error on GeomDB") return false ; } m_pGDB = pGDB ; // verifico l'Id di gruppo if ( ! m_pGDB->ExistsObj( nIdGroup)) { LOG_ERROR( GetEExLogger(), "ImportPly : Error on IdGroup") return false ; } m_nIdGroup = nIdGroup ; // verifico il fattore di scala if ( dScaleFactor < EPS_SMALL) { LOG_ERROR( GetEExLogger(), "ImportPly : Error on ScaleFactor too small (minimum 0.001).") return false ; } m_dScaleFactor = dScaleFactor ; // inizializzo il lettore miniply::PLYReader TheReader( sFile.data()) ; if ( ! TheReader.valid()) { LOG_ERROR( GetEExLogger(), "ImportPly : Error on Init") return false ; } // lettura dati return ReadData( TheReader) ; } //---------------------------------------------------------------------------- bool ImportPly::ReadData( miniply::PLYReader& TheReader) { typedef std::vector FLTVECTOR ; // vettore di float uint32_t propIdxs[3] ; bool bGotVerts = false, bGotFaces = false ; int nVerts = 0 ; FLTVECTOR vVert ; int nTrias = 0 ; INTVECTOR vTria ; while ( TheReader.has_element() && ( ! bGotVerts || ! bGotFaces)) { // Recupero i vertici if ( TheReader.element_is( miniply::kPLYVertexElement) && TheReader.load_element() && TheReader.find_pos( propIdxs)) { nVerts = TheReader.num_rows() ; vVert.resize( 3 * nVerts) ; TheReader.extract_properties( propIdxs, 3, miniply::PLYPropertyType::Float, vVert.data()) ; bGotVerts = true ; } // Recupero gli indici dei vertici dei triangoli delle facce else if ( TheReader.element_is( miniply::kPLYFaceElement) && TheReader.load_element() && TheReader.find_indices( propIdxs)) { bool bPolys = TheReader.requires_triangulation( propIdxs[0]) ; if ( bPolys && ! bGotVerts) { string sOut = " ImportPly : need vertex positions to triangulate faces" ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } if ( bPolys) { nTrias = TheReader.num_triangles( propIdxs[0]) ; vTria.resize( 3 * nTrias) ; TheReader.extract_triangles( propIdxs[0], vVert.data(), nVerts, miniply::PLYPropertyType::Int, vTria.data()) ; } else { nTrias = TheReader.num_rows() ; vTria.resize( 3 * nTrias) ; TheReader.extract_list_property( propIdxs[0], miniply::PLYPropertyType::Int, vTria.data()) ; } bGotFaces = true ; } if ( bGotVerts && bGotFaces) break ; TheReader.next_element() ; } // Controllo lettura effettiuata di vertici e facce if ( ! bGotVerts) { string sOut = " ImportPly : vertex positions not found" ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } if ( ! bGotFaces) { string sOut = " ImportPly : face indices not found" ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } // Costruttore di trimesh da insieme disordinato di triangoli StmFromTriangleSoup StmFts ; if ( ! StmFts.Start()) return false ; // ciclo sui triangoli int nBadTrias = 0 ; for ( int i = 0 ; i < nTrias ; ++ i) { int nT = 3 * i ; Triangle3d Tria ; for ( int j = 0 ; j < 3 ; ++ j) { int nV = 3 * vTria[nT+j] ; Point3d ptP( vVert[nV], vVert[nV+1], vVert[nV+2]) ; ptP *= m_dScaleFactor ; Tria.SetP( j, ptP) ; } if ( Tria.Validate( true)) { if ( ! StmFts.AddTriangle( Tria)) { string sOut = " ImportPly : error adding triangle" ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } } else ++ nBadTrias ; } if ( nBadTrias > 0) { string sOut = " ImportPly : found " + ToString( nBadTrias) + " bad triangles" ; 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 ; }