9331803efc
- aggiunta importazione formato PLY - migliorata importazione formato OFF.
170 lines
5.5 KiB
C++
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 ;
|
|
}
|