Files
EgtExchange/ImportStl.cpp
T
Dario Sassi 04690b690a EgtExchange :
- aggiunta importazione STL ASCII.
2014-04-05 20:48:08 +00:00

237 lines
6.8 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : ImportStl.cpp Data : 04.04.14 Versione : 1.5d1
// Contenuto : Implementazione della classe per l'importazione di STL.
//
//
//
// Modifiche : 04.04.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ImportStl.h"
#include "DllMain.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDEv/Include/EGnScan.h"
#include "/EgtDev/Include/EgnStringUtils.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
using namespace std ;
//----------------------------------------------------------------------------
IImportStl*
CreateImportStl( void)
{
return static_cast<IImportStl*> ( new(nothrow) ImportStl) ;
}
//----------------------------------------------------------------------------
bool
ImportStl::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup)
{
// inizializzo lo scanner
Scanner TheScanner ;
if ( ! TheScanner.Init( sFile)) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error on Init")
return false ;
}
// verifico il DB geometrico
if ( pGDB == nullptr) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error on GeomDB")
return false ;
}
m_pGDB = pGDB ;
// verifico l'Id di gruppo
if ( ! m_pGDB->ExistsObj( nIdGroup)) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error on IdGroup")
return false ;
}
m_nIdGroup = nIdGroup ;
// ciclo di lettura degli oggetti
bool bOk = true ;
bool bEnd = false ;
do {
if ( ! LoadSolid( TheScanner, bEnd)) {
bOk = false ;
string sOut = "ImportStl : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ;
LOG_ERROR( GetEExLogger(), sOut.c_str())
}
} while ( bOk && ! bEnd) ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ImportStl::LoadSolid( Scanner& TheScanner, bool& bEnd)
{
string sLine ;
STRVECTOR vsParams ;
// recupero la prima linea
if ( ! TheScanner.GetLine( sLine)) {
bEnd = true ;
return true ;
}
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 1 parametro
if ( vsParams.size() < 1)
return false ;
// deve essere la parola chiave "solid"
if ( vsParams[0] != "solid")
return false ;
// se c'è un secondo parametro è il nome
string sName ;
if ( vsParams.size() >= 2)
sName = vsParams[1] ;
// preparo l'oggetto TriMesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM)) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error allocating SurfTriMesh")
return false ;
}
if ( ! pSTM->Init( 3, 1)) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error initialising SurfTriMesh")
return false ;
}
// ciclo di lettura dei triangoli
bool bOk = true ;
bool bTEnd = false ;
do {
if ( ! LoadTriangle( TheScanner, Get( pSTM), bTEnd)) {
bOk = false ;
string sOut = "ImportStl : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ;
LOG_ERROR( GetEExLogger(), sOut.c_str())
}
} while ( bOk && ! bTEnd) ;
// recupero la linea di terminazione dell'oggetto
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 1 parametro
if ( vsParams.size() < 1)
return false ;
// deve essere la parola chiave "endsolid" oppure "end" "solid"
if ( vsParams[0] != "endsolid" && vsParams[0] != "end")
return false ;
// valido la superficie e calcolo le adiacenze
if ( ! pSTM->AdjustTopology()) {
LOG_ERROR( GetEExLogger(), "ImportStl : Error adjusting topology in SurfTriMesh")
return false ;
}
// inserisco l'oggetto nel DB geometrico
int nIdNew = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nIdGroup, Release( pSTM)) ;
// se previsto il nome, lo assegno
if ( ! sName.empty())
m_pGDB->SetName( nIdNew, sName) ;
bEnd = false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportStl::LoadTriangle( Scanner& TheScanner, ISurfTriMesh* pSTM, bool& bEnd)
{
string sLine ;
STRVECTOR vsParams ;
// recupero la prima linea
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 1 parametro
if ( vsParams.size() < 1)
return false ;
// deve essere la parola chiave "facet"
if ( vsParams[0] != "facet") {
TheScanner.UngetLine( sLine) ;
bEnd = true ;
return true ;
}
// ignoro il resto
// recupero la seconda linea
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 2 parametri
if ( vsParams.size() < 2)
return false ;
// devono essere le parole chiave "outer" e "loop"
if ( vsParams[0] != "outer" || vsParams[1] != "loop")
return false ;
// ciclo sui tre vertici
int nIdV[3] ;
for ( int i = 0 ; i < 3 ; ++ i) {
// recupero una linea
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 4 parametri
if ( vsParams.size() < 4)
return false ;
// parola chiave "vertex"
if ( vsParams[0] != "vertex")
return false ;
// tre coordinate del vertice
Point3d ptP ;
if ( ! FromString( vsParams[1], ptP.x) ||
! FromString( vsParams[2], ptP.y) ||
! FromString( vsParams[3], ptP.z))
return false ;
// aggiungo il vertice
if ( ( nIdV[i] = pSTM->AddVertex( ptP)) == -1)
return false ;
}
// inserisco il triangolo
if( pSTM->AddTriangle( nIdV) == -1)
return false ;
// nuova linea
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 1 parametro
if ( vsParams.size() < 1)
return false ;
// parola chiave "endloop"
if ( vsParams[0] != "endloop")
return false ;
// nuova linea
if ( ! TheScanner.GetLine( sLine))
return false ;
// la divido in parametri
Tokenize( sLine, " ", vsParams) ;
// almeno 1 parametro
if ( vsParams.size() < 1)
return false ;
// parola chiave "endfacet"
if ( vsParams[0] != "endfacet")
return false ;
bEnd = false ;
return true ;
}