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

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 ;
}