Files
EgtExchange/Export3dm.cpp
T
Daniele Bariletti 2c9da3e14d EgtExchange :
- aggiunta del 3dm Export. Da completare.
2023-09-21 17:04:32 +02:00

301 lines
9.3 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2023
//----------------------------------------------------------------------------
// File : Export3dm.cpp Data : 21.09.23 Versione :
// Contenuto : Implementazione della classe per l'esportazione in formato 3dm.
//
//
//
// Modifiche : 21.09.23 DB Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "Export3dm.h"
#include "DllMain.h"
#include "/EgtDev/Include/EExDllMain.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include "/EgtDev/Include/EgtKeyCodes.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <fstream>
#include "C:/EgtDev/opennurbs/opennurbs.h"
using namespace std ;
//----------------------------------------------------------------------------
IExport3dm*
CreateExport3dm( void)
{
// verifico la chiave e le opzioni
if ( ! VerifyKey( KEYOPT_EEX_EXPBASE))
return nullptr ;
// creo l'oggetto
return static_cast<IExport3dm*> ( new(nothrow) Export3dm) ;
}
//----------------------------------------------------------------------------
bool
Export3dm::SetOptions( int nFilter)
{
m_nFilter = nFilter ;
return true ;
}
//----------------------------------------------------------------------------
bool
Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile)
{
// verifico il DB geometrico
if ( pGDB == nullptr) {
LOG_ERROR( GetEExLogger(), "Export3dm : Error on GeomDB")
return false ;
}
// verifico l'Id dell'oggetto da esportare
if ( ! pGDB->ExistsObj( nId)) {
LOG_ERROR( GetEExLogger(), "Export3dm : Error on Id")
return false ;
}
// file settings (units, tolerances, views, ...)
// OPTIONAL - change values from defaults
m_model.m_settings.m_ModelUnitsAndTolerances.m_unit_system = ON::LengthUnitSystem::Meters;
m_model.m_settings.m_ModelUnitsAndTolerances.m_absolute_tolerance = 0.01;
m_model.m_settings.m_ModelUnitsAndTolerances.m_angle_tolerance = ON_PI/180.0; // radians
m_model.m_settings.m_ModelUnitsAndTolerances.m_relative_tolerance = 0.01; // 1%
//// apro il file di testo in scrittura
//m_Writer.Close() ;
//if ( ! m_Writer.Init( sFile)) {
// LOG_ERROR( GetEExLogger(), "Export3dm : Error on open file")
// return false ;
//}
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( IsNull( pIter))
return false ;
pIter->GoTo( nId) ;
// esporto l'oggetto e i suoi eventuali figli
bool bOk = ExportObject( *pIter) ;
//// chiudo il file
//if ( ! m_Writer.Close())
// bOk = false ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Export3dm::ExportObject( const IGdbIterator& iIter)
{
switch ( iIter.GetGdbType()) {
case GDB_TY_GEO :
{
// recupero l'oggetto geometrico
const IGeoObj* pGeoObj = 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))
// return false ;
// break ;
//case SRF_FLATRGN :
// if ( ! ExportSFR( sName, pGeoObj, frFrame))
// return false ;
// break ;
case CRV_ARC : {
break ;
}
case CRV_BEZIER : {
break ;
}
case CRV_COMPO : {
break ;
}
case CRV_LINE : {
if ( ! ExportCrvLine( sName, pGeoObj, frFrame))
return false ;
break ;
}
default :
break ;
}
}
}
return true ;
case GDB_TY_GROUP :
// esploro il gruppo
return ScanGroup( iIter) ;
default :
return false ;
}
}
ON_3dmObjectAttributes* Internal_CreateManagedAttributes(
int layer_index,
const wchar_t* name
)
{
ON_3dmObjectAttributes* attributes = new ON_3dmObjectAttributes();
attributes->m_layer_index = layer_index;
attributes->m_name = name;
return attributes;
}
//----------------------------------------------------------------------------
ON_3dPoint
Export3dm::ConvertPoint( const Point3d& pt)
{
ON_3dPoint onPt( pt.x,pt.y,pt.z) ;
return onPt ;
}
//----------------------------------------------------------------------------
bool
Export3dm::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
Export3dm::ExportSFR( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ISurfFlatRegion* pSFR = GetSurfFlatRegion( pGeoObj) ;
if ( pSFR == nullptr)
return false ;
// ricavo la trimesh equivalente
const ISurfTriMesh* pStm = pSFR->GetAuxSurf() ;
return ExportSTM( sName, pStm, frFrame) ;
}
//----------------------------------------------------------------------------
bool
Export3dm::ExportSTM( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// inizio oggetto
bool bOk = m_Writer.OutText( "solid " + sName) ;
// 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
bOk = bOk && m_Writer.OutText( " facet normal " + ToString( Tria.GetN().x) +
" " + ToString( Tria.GetN().y) +
" " + ToString( Tria.GetN().z)) ;
m_Writer.OutText( " outer loop") ;
for ( int i = 0 ; i < 3 ; ++ i) {
bOk = bOk && m_Writer.OutText( " vertex " + ToString( Tria.GetP( i).x) +
" " + ToString( Tria.GetP( i).y) +
" " + ToString( Tria.GetP( i).z)) ;
}
bOk = bOk && m_Writer.OutText( " endloop") ;
bOk = bOk && m_Writer.OutText( " endfacet") ;
// passo al successivo
nId = pSTM->GetNextTriangle( nId, Tria) ;
}
// termino oggetto
bOk = bOk && m_Writer.OutText( "endsolid") ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Export3dm::ExportCrvLine( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// verifico oggetto
const ICurveLine* pCrvL = GetCurveLine( pGeoObj) ;
if ( pCrvL == nullptr)
return false ;
bool bOk = true ;
int nLayer = 0 ;
std::wstring ws = std::wstring(sName.begin(), sName.end());
const wchar_t* wsName = ws.c_str();
ON_3dmObjectAttributes* pOnAttr_CrvL = Internal_CreateManagedAttributes( nLayer, wsName) ;
Point3d ptStart, ptEnd ;
pCrvL->GetStartPoint ( ptStart) ;
pCrvL->GetEndPoint ( ptEnd) ;
ON_Object* onCrvLine = new ON_LineCurve( ON_Line( ConvertPoint( ptStart), ConvertPoint( ptEnd)));
ON_ModelComponentReference mcr = m_model.AddManagedModelGeometryComponent( onCrvLine, pOnAttr_CrvL);
if ( mcr.IsEmpty())
bOk = false ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Export3dm::ScanGroup( const IGdbIterator& iIter)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( IsNull( pIter))
return false ;
// scandisco il gruppo
bool bOk = true ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
if ( ! ExportObject( *pIter))
bOk = false ;
}
return bOk ;
}