04690b690a
- aggiunta importazione STL ASCII.
237 lines
6.8 KiB
C++
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 ;
|
|
}
|