Files
Dario Sassi 9331803efc EgtExchange 2.7b2 :
- aggiunta importazione formato PLY
- migliorata importazione formato OFF.
2025-03-02 19:42:10 +01:00

170 lines
5.5 KiB
C++

//----------------------------------------------------------------------------
// 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<IImportPly*> ( 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<float> 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<ISurfTriMesh> pSTM( StmFts.GetSurf()) ;
int nIdNew = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nIdGroup, Release( pSTM)) ;
if ( nIdNew == GDB_ID_NULL)
return false ;
return true ;
}