9331803efc
- aggiunta importazione formato PLY - migliorata importazione formato OFF.
207 lines
6.2 KiB
C++
207 lines
6.2 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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<IImportOff*> ( 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<ISurfTriMesh> 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<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 ;
|
|
}
|