//---------------------------------------------------------------------------- // 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 #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 ( 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 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 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 ; }