Files
EgtExchange/ExportStl.cpp
T
Dario Sassi 8c69460cb1 EgtExchange 1.5h2 :
- aggiunto esportatore STL
- aggiunto esportatore DXF.
2014-08-12 07:43:46 +00:00

217 lines
7.0 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : ExportStl.cpp Data : 07.08.14 Versione : 1.5h2
// Contenuto : Implementazione della classe per l'esportazione in formato STL.
//
//
//
// Modifiche : 07.08.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ExportStl.h"
#include "DllMain.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EgnStringUtils.h"
#include "/EgtDev/Include/EgnStringConverter.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <fstream>
using namespace std ;
//----------------------------------------------------------------------------
IExportStl*
CreateExportStl( void)
{
return static_cast<IExportStl*> ( new(nothrow) ExportStl) ;
}
//----------------------------------------------------------------------------
bool
ExportStl::SetOptions( int nFilter)
{
m_nFilter = nFilter ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportStl::Export( IGeomDB* pGDB, int nId, const string& sFile)
{
// verifico il DB geometrico
if ( pGDB == nullptr) {
LOG_ERROR( GetEExLogger(), "ExportStl : Error on GeomDB")
return false ;
}
// verifico l'Id dell'oggetto da esportare
if ( ! pGDB->ExistsObj( nId)) {
LOG_ERROR( GetEExLogger(), "ExportStl : Error on Id")
return false ;
}
// apro il file di testo in scrittura
ofstream OutFile( stringtoW( sFile), ios::out, _SH_DENYWR) ;
if ( ! OutFile.good()) {
LOG_ERROR( GetEExLogger(), "ExportStl : Error on open file")
return false ;
}
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( ! ::IsValid( pIter))
return false ;
pIter->GoTo( nId) ;
// esporto l'oggetto e i suoi eventuali figli
bool bOk = ExportObject( *pIter, OutFile) ;
// chiudo il file
if ( ! OutFile.good() || ! OutFile.is_open())
bOk = false ;
if ( OutFile.is_open())
OutFile.close() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportStl::ExportObject( const IGdbIterator& iIter, ofstream& OutFile)
{
switch ( iIter.GetGdbType()) {
case GDB_TY_GEO :
{
// recupero l'oggetto geometrico
const IGeoObj* pGeoObj =(const_cast<IGdbIterator*>(&iIter))->GetGeoObj() ;
if ( pGeoObj == nullptr)
return true ;
// recupero il riferimento globale dell'oggetto
Frame3d frFrame ;
if ( ! iIter.GetGlobFrame( frFrame))
return false ;
// recupero il livello dell'oggetto
int nLev = GDB_LV_USER ;
iIter.GetCalcLevel( nLev) ;
// recupero il modo dell'oggetto
int nMode = GDB_MD_STD ;
iIter.GetCalcMode( nMode) ;
// recupero lo stato dell'oggetto
int nStat = GDB_ST_ON ;
iIter.GetCalcStatus( nStat) ;
// se il filtro lo abilita
if ( TestFilter( nLev, nMode, nStat)) {
// recupero eventuale nome
string sName ;
if ( ! iIter.GetName( sName))
sName = ToString( iIter.GetId()) ;
// emetto l'oggetto
switch ( pGeoObj->GetType()) {
case SRF_TRIMESH :
if ( ! ExportSTM( sName, pGeoObj, frFrame, OutFile))
return false ;
break ;
default :
break ;
}
}
}
return true ;
case GDB_TY_GROUP :
// esploro il gruppo
return ScanGroup( iIter, OutFile) ;
default :
return false ;
}
}
//----------------------------------------------------------------------------
bool
ExportStl::TestFilter( int nLev, int nMode, int nStat)
{
if ( ( nLev == GDB_LV_USER && ( m_nFilter & EEXFLT_LEVUSER) == 0) ||
( nLev == GDB_LV_SYSTEM && ( m_nFilter & EEXFLT_LEVSYSTEM) == 0) ||
( nLev == GDB_LV_TEMP && ( m_nFilter & EEXFLT_LEVTEMP) == 0))
return false ;
if ( ( nMode == GDB_MD_STD && ( m_nFilter & EEXFLT_MODESTD) == 0) ||
( nMode == GDB_MD_LOCKED && ( m_nFilter & EEXFLT_MODELOCKED) == 0) ||
( nMode == GDB_MD_HIDDEN && ( m_nFilter & EEXFLT_MODEHIDDEN) == 0))
return false ;
if ( ( nStat == GDB_ST_OFF && ( m_nFilter & EEXFLT_STAOFF) == 0) ||
( nStat == GDB_ST_ON && ( m_nFilter & EEXFLT_STAON) == 0) ||
( nStat == GDB_ST_SEL && ( m_nFilter & EEXFLT_STASEL) == 0))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportStl::ExportSTM( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame,
ofstream& OutFile)
{
// verifico oggetto
const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ;
if ( pSTM == nullptr)
return false ;
try {
// inizio oggetto
OutFile << "solid " << sName << endl ;
// ciclo sui triangoli della trimesh
Triangle3d Tria ;
int nId = pSTM->GetFirstTriangle( Tria) ;
while ( nId != SVT_NULL) {
// lo porto in coordinate globali
Tria.ToGlob( frFrame) ;
// emetto il triangolo
OutFile << " facet normal " << ToString( Tria.GetN().x) <<
" " << ToString( Tria.GetN().y) <<
" " << ToString( Tria.GetN().z) << endl ;
OutFile << " outer loop" << endl ;
for ( int i = 0 ; i < 3 ; ++ i) {
OutFile << " vertex " << ToString( Tria.GetP( i).x) <<
" " << ToString( Tria.GetP( i).y) <<
" " << ToString( Tria.GetP( i).z) << endl ;
}
OutFile << " endloop" << endl ;
OutFile << " endfacet" << endl ;
// passo al successivo
nId = pSTM->GetNextTriangle( nId, Tria) ;
}
// termino oggetto
OutFile << "endsolid" << endl ;
}
catch( ...)
{ return false ; }
return true ;
}
//----------------------------------------------------------------------------
bool
ExportStl::ScanGroup( const IGdbIterator& iIter, ofstream& OutFile)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( ! ::IsValid( pIter))
return false ;
// scandisco il gruppo
bool bOk = true ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
if ( ! ExportObject( *pIter, OutFile))
bOk = false ;
}
return bOk ;
}