//---------------------------------------------------------------------------- // 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/EE3DllMain.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkGeoObjType.h" #include "/EgtDev/Include/EGkGeoPoint3d.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 "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Extern/opennurbs/Include/opennurbs.h" #include #include using namespace std ; //N.B.: // se si vuole richiamare qualche variabile di default definita in una classe come statica e a cui viene assegnato un valore // nel file opennurbs_statics.cpp bisogna richiamarla in questo elenco per evitare problemi di compilazione ( errore di LINK) //---------------------------------------------------------------------------- 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 ; CalcGroupFilter() ; return true ; } //---------------------------------------------------------------------------- static void Internal_SetExampleModelProperties( ONX_Model& model, const char* source_file_name) { const bool bHaveFileName = ( nullptr != source_file_name && 0 != source_file_name[0]) ; if ( ! bHaveFileName) source_file_name = "" ; model.m_sStartSectionComments = "This file was created using openNURBS to convert an .nge into .3dm" ; // set application information const ON_wString wide_source_file_name( source_file_name) ; model.m_properties.m_Application.m_application_URL = L"http://www.opennurbs.org" ; // set revision history information model.m_properties.m_RevisionHistory.NewRevision() ; } //---------------------------------------------------------------------------- bool Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile) { Internal_SetExampleModelProperties( m_model, sFile.c_str()) ; ON::Begin() ; // verifico il DB geometrico if ( pGDB == nullptr) { LOG_ERROR( GetEE3Logger(), "Export3dm : Error on GeomDB") return false ; } // verifico l'Id dell'oggetto da esportare if ( ! pGDB->ExistsObj( nId)) { LOG_ERROR( GetEE3Logger(), "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::Millimeters ; 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% m_model.m_settings.m_current_material_source = ON::object_material_source::material_from_object ; m_model.m_settings.m_RenderSettings.m_bFlatShade = true ; // 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, 0) ; // stampo il file int version = 7 ; // errors printed to stdout ON_TextLog error_log ; // writes model to archive bOk = bOk && m_model.Write( ConvertString( sFile).c_str(), version, &error_log) ; ON::End() ; return bOk ; } //---------------------------------------------------------------------------- bool Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer) { // 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) ; int nType = iIter.GetGdbType() ; // se il filtro lo abilita if ( TestFilter( nLev, nMode, nStat, nType == GDB_TY_GROUP)) { switch ( nType) { case GDB_TY_GEO : { // recupero il riferimento globale dell'oggetto Frame3d frFrame ; if ( ! iIter.GetGlobFrame( frFrame)) return false ; //recupero il colore dell'oggetto Color cCol ; iIter.GetCalcMaterial( cCol) ; // recupero eventuale nome string sName ; if ( ! iIter.GetName( sName)) sName = ToString( iIter.GetId()) ; // emetto l'oggetto switch ( iIter.GetGeoType()) { case GEO_PNT3D: { if ( ! ExportPnt( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } case SRF_BEZIER: { if ( ! ExportSrfBz( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } case SRF_FLATRGN : case SRF_TRIMESH : if ( ! ExportSTM( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; case CRV_ARC : { if ( ! ExportCrvArc( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } case CRV_BEZIER : { if ( ! ExportCrvBezier( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } case CRV_COMPO : { if ( ! ExportCrvCompo( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } case CRV_LINE : { if ( ! ExportCrvLine( sName, iIter, frFrame, cCol, nLayer)) return false ; break ; } default : break ; } } return true ; case GDB_TY_GROUP: { int nLayer = iIter.GetId() ; if ( nLayer == 0) { m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, m_model.LayerFromIndex( 0).ModelComponentId()) ; return ScanGroup( iIter, nLayer) ; } // creo il layer e setto le proprietà ON_Layer* layer = new ON_Layer() ; std::string sLayName ; iIter.GetName( sLayName) ; if ( sLayName == "" ) { sLayName = "Layer " + ToString( nLayer) ; } layer->SetName( ConvertString( sLayName).c_str()) ; layer->SetIndex( nLayer) ; ON_Color onCol( 0, 0, 0) ; // black layer->SetColor( onCol) ; layer->SetVisible( true) ; layer->SetLocked( false) ; int nParent = iIter.GetParentId() ; if ( nParent != 0) { // setto il parent const ON_Layer* onParLay = ON_Layer::Cast( m_model.LayerFromIndex( m_mLayer[nParent]).ModelComponent()) ; layer->SetParentLayerId( onParLay->Id()) ; } // copio le info STRVECTOR vStrInfo, vStrInfo_split ; iIter.GetAllInfo( vStrInfo) ; for ( string sInfo : vStrInfo) { Tokenize( sInfo, "=", vStrInfo_split) ; layer->SetUserString( ConvertString( vStrInfo_split[0]).c_str(), ConvertString( vStrInfo_split[1]).c_str()) ; } // aggiungo il layer ON_ModelComponentReference mcr = m_model.AddManagedModelComponent( layer) ; int nIndex = mcr.ModelComponentIndex() ; m_mLayer.insert( pair< int, int>( nLayer, nIndex)) ; // esploro il gruppo return ScanGroup( iIter, nIndex) ; } default : return false ; } } return true ; } //---------------------------------------------------------------------------- bool Export3dm::AddObjectToModel( const IGdbIterator& iIter, ON_Object* onObject, const int& nLayer, const std::string& sName, const Color& cCol, ON_3dmObjectAttributes* pOnAttr) { if ( pOnAttr == nullptr) pOnAttr = new ON_3dmObjectAttributes() ; pOnAttr->m_layer_index = nLayer ; pOnAttr->m_name = ConvertString( sName).c_str() ; pOnAttr->SetColorSource( ON::color_from_object) ; //N.B. RHINO ha i valori di Alpha invertiti rispetto ai nostri, oltre che su una scala diversa! per loro 0 = opaco e 255 = trasparente // per noi invece 0 = trasparente, 100 = opaco ON_Color onCol( cCol.GetIntRed(), cCol.GetIntGreen(), cCol.GetIntBlue(), abs( int( cCol.GetIntAlpha() * 2.55) - 255)) ; pOnAttr->m_color = onCol ; // se è una mesh aggiungo il materiale if ( const ON_Mesh* onMesh = ON_Mesh::Cast( onObject)) { // aggiungo il materiale al modello se necessario std::string sCol = ToString(cCol.GetIntRed()) + "," + ToString( cCol.GetIntGreen()) + "," + ToString( cCol.GetIntBlue()) ; if ( m_mMaterial.find( sCol) == m_mMaterial.end()) { ON_Material* onMat = new ON_Material ; ON_Color onCAmb( 126, 126, 126) ; // gray126 onMat->m_reflection_glossiness = 0.0 ; onMat->SetEmission( onCol) ; onMat->SetDiffuse( onCol) ; onMat->SetAmbient( onCAmb) ; onMat->SetReflectivity( 0) ; ON_ModelComponentReference mcr = m_model.AddManagedModelComponent( onMat) ; int nIndex = mcr.ModelComponentIndex() ; m_mMaterial.insert( pair< std::string, int>( sCol, nIndex)) ; pOnAttr->SetMaterialSource( ON::object_material_source::material_from_object) ; pOnAttr->m_material_index = nIndex ; } // sennò richiamo un materiale già definito else { pOnAttr->SetMaterialSource( ON::object_material_source::material_from_object) ; pOnAttr->m_material_index = m_mMaterial[sCol] ; } } // copio le info STRVECTOR vStrInfo, vStrInfo_split ; iIter.GetAllInfo(vStrInfo) ; for ( string sInfo : vStrInfo) { Tokenize( sInfo, "=", vStrInfo_split) ; pOnAttr->SetUserString( ConvertString( vStrInfo_split[0]).c_str(), ConvertString( vStrInfo_split[1]).c_str()) ; } // aggiungo al modello ON_ModelComponentReference mcr = m_model.AddManagedModelGeometryComponent( onObject, pOnAttr) ; return ! mcr.IsEmpty() ; } //---------------------------------------------------------------------------- bool Export3dm::AddInfoToObject( const IGdbIterator& iIter, ON_Object* onObject) { // copio le info STRVECTOR vStrInfo, vStrInfo_split ; iIter.GetAllInfo( vStrInfo) ; for ( string sInfo : vStrInfo) { Tokenize( sInfo, "=", vStrInfo_split) ; onObject->SetUserString( ConvertString( vStrInfo_split[0]).c_str(), ConvertString( vStrInfo_split[1]).c_str()) ; } return true ; } //---------------------------------------------------------------------------- bool Export3dm::TestFilter( int nLev, int nMode, int nStat, bool bGroup) { int nFilter = bGroup ? m_nGroupFilter : m_nFilter ; if ( ( nLev == GDB_LV_USER && ( nFilter & EEXFLT_LEVUSER) == 0) || ( nLev == GDB_LV_SYSTEM && ( nFilter & EEXFLT_LEVSYSTEM) == 0) || ( nLev == GDB_LV_TEMP && ( nFilter & EEXFLT_LEVTEMP) == 0)) return false ; if ( ( nMode == GDB_MD_STD && ( nFilter & EEXFLT_MODESTD) == 0) || ( nMode == GDB_MD_LOCKED && ( nFilter & EEXFLT_MODELOCKED) == 0) || ( nMode == GDB_MD_HIDDEN && ( nFilter & EEXFLT_MODEHIDDEN) == 0)) return false ; if ( ( nStat == GDB_ST_OFF && ( nFilter & EEXFLT_STAOFF) == 0) || ( nStat == GDB_ST_ON && ( nFilter & EEXFLT_STAON) == 0) || ( nStat == GDB_ST_SEL && ( nFilter & EEXFLT_STASEL) == 0)) return false ; return true ; } //---------------------------------------------------------------------------- bool Export3dm::CalcGroupFilter( void) { m_nGroupFilter = 0 ; // Status if ( ( m_nFilter & EEXFLT_STASEL) != 0) m_nGroupFilter += EEXFLT_STASEL + EEXFLT_STAOFF + EEXFLT_STAON ; else if ( ( m_nFilter & EEXFLT_STAOFF) != 0) m_nGroupFilter += EEXFLT_STAOFF + EEXFLT_STAON ; else m_nGroupFilter += EEXFLT_STAON ; // Mode if ( ( m_nFilter & EEXFLT_MODELOCKED) != 0) m_nGroupFilter += EEXFLT_MODELOCKED + EEXFLT_MODEHIDDEN + EEXFLT_MODESTD ; else if ( ( m_nFilter & EEXFLT_MODEHIDDEN) != 0) m_nGroupFilter += EEXFLT_MODEHIDDEN + EEXFLT_MODESTD ; else m_nGroupFilter += EEXFLT_MODESTD ; // Level if ( ( m_nFilter & EEXFLT_LEVSYSTEM) != 0) m_nGroupFilter += EEXFLT_LEVSYSTEM + EEXFLT_LEVTEMP + EEXFLT_LEVUSER ; else if ( ( m_nFilter & EEXFLT_LEVTEMP) != 0) m_nGroupFilter += EEXFLT_LEVTEMP + EEXFLT_LEVUSER ; else m_nGroupFilter += EEXFLT_LEVUSER ; return true ; } //---------------------------------------------------------------------------- bool Export3dm::ExportPnt(const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pGeoPnt( GetGeoPoint3d( pGeoObj->Clone())) ; if ( IsNull( pGeoPnt)) return false ; // lo porto nel riferimento globale pGeoPnt->ToGlob( frFrame) ; Point3d pt = pGeoPnt->GetPoint() ; ON_Point* onPt = new ON_Point( ConvertPoint( pt)) ; // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onPt, nLayer, sName, cCol) ; ; } //---------------------------------------------------------------------------- bool Export3dm::ExportSrfBz( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { //MANCA DA IMPLEMENTARE IL TRIM DELLE SUPERFICI!!///////////////////////////////////////////////////////////////////////////////////////////////////// // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pSrfBz( GetSurfBezier( pGeoObj->Clone())) ; if ( IsNull( pSrfBz)) return false ; // lo porto nel riferimento globale pSrfBz->ToGlob( frFrame) ; bool bOk = true ; int nDegU, nDegV, nSpanU, nSpanV ; bool bRat = false ; bool bTrimmed = false ; pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ; int nCPU = nDegU * nSpanU + 1 ; int nCPV = nDegV * nSpanV + 1 ; ON_NurbsSurface* onNurbsSurf = new ON_NurbsSurface( 3, bRat, nDegU + 1, nDegV + 1, nCPU, nCPV) ; for ( int u = 0 ; u < nCPU ; ++u) { for ( int v = 0 ; v < nCPV ; ++v) { Point3d ptCV = pSrfBz->GetControlPoint( u, v, &bOk) ; if ( ! bRat) { onNurbsSurf->SetCV( u, v, ConvertPoint( ptCV)) ; } else { double dW = pSrfBz->GetControlWeight( u, v, &bOk) ; onNurbsSurf->SetCV( u, v, ConvertPoint( ptCV * dW)) ; onNurbsSurf->SetWeight( u, v, dW) ; } } } // imposto il vettore dei nodi in U int nKnotCountU = nDegU + nCPU - 1 ; double dKnot = 0 ; // per costruzione nKnotCount é un multiplo di nDegU for ( int u = 0 ; u < int ( nKnotCountU / nDegU) ; ++u) { for ( int p = 0 ; p < nDegU ; ++p) onNurbsSurf->SetKnot( 0, u * nDegU + p, dKnot) ; ++dKnot ; } // imposto il vettore dei nodi in V int nKnotCountV = nDegV + nCPV - 1 ; dKnot = 0 ; // per costruzione nKnotCount é un multiplo di nDegU for ( int v = 0 ; v < int ( nKnotCountV / nDegV) ; ++v) { for ( int p = 0 ; p < nDegV ; ++p) onNurbsSurf->SetKnot( 0, v * nDegV + p, dKnot) ; ++dKnot ; } // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onNurbsSurf, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- bool Export3dm::ExportSTM( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pSrfTm ; if ( pGeoObj->GetType() == SRF_TRIMESH) pSrfTm.Set( GetSurfTriMesh( pGeoObj->Clone())) ; else { const ISurfFlatRegion* pSrfFr = GetSurfFlatRegion( pGeoObj) ; const ISurfTriMesh* pSrfTm_ = pSrfFr->GetAuxSurf() ; if ( pSrfTm_ == nullptr){ return false ; } pSrfTm.Set( pSrfTm_->Clone()) ; } if ( IsNull( pSrfTm)) return false ; // lo porto nel frame globale pSrfTm->ToGlob( frFrame) ; int nVertices = pSrfTm->GetVertexCount() ; int nTriangles = pSrfTm->GetTriangleCount() ; ON_Mesh* onMesh = new ON_Mesh ; for ( int v = 0 ; v < nVertices ; ++v) { Point3d pt ; pSrfTm->GetVertex( v, pt) ; onMesh->SetVertex( v, ConvertPoint( pt)) ; } for ( int t = 0 ; t < nTriangles ; ++t) { int nIdVert[3] ; pSrfTm->GetTriangle( t, nIdVert) ; onMesh->SetTriangle( t, nIdVert[0], nIdVert[1], nIdVert[2]) ; } // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onMesh, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- ON_ArcCurve* Export3dm::ConvertCrvArc( const ICurveArc* pCrvArc) { double dRad = pCrvArc->GetRadius() ; Point3d ptCen ; pCrvArc->GetCenterPoint( ptCen) ; PtrOwner onArcCrv( new ON_ArcCurve()) ; if ( ! pCrvArc->IsACircle()) { Vector3d vtZ = pCrvArc->GetNormVersor() ; Vector3d vtX, vtY ; vtX = pCrvArc->GetStartVersor() ; vtY = vtZ ^ vtX ; double dAngDeg = pCrvArc->GetAngCenter() ; ON_Plane onPlane( ConvertPoint( ptCen), ConvertVector( vtX), ConvertVector( vtY)) ; onArcCrv.Set( new ON_ArcCurve( ON_Arc( onPlane, dRad, dAngDeg * DEGTORAD))) ; } else onArcCrv.Set( new ON_ArcCurve ( ON_Circle( ConvertPoint( ptCen), dRad))) ; return Release( onArcCrv) ; } //---------------------------------------------------------------------------- bool Export3dm::ExportCrvArc( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pCrvArc( GetCurveArc( pGeoObj->Clone())) ; if ( IsNull( pCrvArc)) return false ; // lo porto nel fram globale pCrvArc->ToGlob( frFrame) ; ON_ArcCurve* onArcCrv = ConvertCrvArc( pCrvArc) ; if ( onArcCrv == nullptr) return false ; // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onArcCrv, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- ON_NurbsCurve* Export3dm::ConvertCrvBezier( const ICurveBezier* pCrvBz) { // creo l'oggetto da esportare int nDeg = pCrvBz->GetDegree() ; int nCV = nDeg + 1 ; PtrOwner onNurbsCrv( new ON_NurbsCurve( 3, // dim pCrvBz->IsRational(), // bRat nDeg + 1, // order = deg + 1 nCV)) ; // numero di CP // imposto i punti di controllo con gli eventuali pesi if ( ! pCrvBz->IsRational()) { bool bOk = true ; for ( int i = 0 ; i < nCV ; ++i) { ON_3dPoint onPt = ConvertPoint( pCrvBz->GetControlPoint( i, &bOk)) ; onNurbsCrv->SetCV( i, onPt) ; } } else { bool bOk = true ; for ( int i = 0 ; i < nCV ; ++i) { ON_3dPoint onPt = ConvertPoint( pCrvBz->GetControlPoint( i, &bOk)) ; double dWeight = pCrvBz->GetControlWeight( i, &bOk) ; onNurbsCrv->SetCV( i, onPt * dWeight) ; onNurbsCrv->SetWeight( i, dWeight) ; } } // imposto il vettore dei nodi int nKnotCount = nDeg + nCV - 1 ; double dKnot = 0 ; for ( int u = 0 ; u < int ( nKnotCount / nDeg) ; ++u) { for ( int p = 0 ; p < nDeg ; ++p) onNurbsCrv->SetKnot( u * nDeg + p, dKnot) ; ++dKnot ; } return Release( onNurbsCrv) ; } //---------------------------------------------------------------------------- bool Export3dm::ExportCrvBezier( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pCrvBz( GetCurveBezier( pGeoObj->Clone())) ; if ( IsNull( pCrvBz)) return false ; // lo porto nel riferimento globale pCrvBz->ToGlob( frFrame) ; ON_NurbsCurve* onNurbsCrv = ConvertCrvBezier( pCrvBz) ; if ( onNurbsCrv == nullptr) return false ; // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onNurbsCrv, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- bool Export3dm::ExportCrvCompo( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pCrvCompo( GetCurveComposite( pGeoObj->Clone())) ; if ( IsNull( pCrvCompo)) return false ; // lo porto nel riferimento globale pCrvCompo->ToGlob( frFrame) ; ON_PolyCurve* onPolyCrv = new ON_PolyCurve ; for ( const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; pCrv != nullptr ; pCrv = pCrvCompo->GetNextCurve()) { GeoObjType type = pCrv->GetType() ; switch ( type) { case CRV_LINE : { PtrOwner pCrvL( GetCurveLine( pCrv->Clone())) ; if ( IsNull( pCrvL)) { delete onPolyCrv ; return false ; } ON_LineCurve* onLine = ConvertCrvLine( pCrvL) ; if ( onLine == nullptr) { delete onPolyCrv ; return false ; } onPolyCrv->Append( onLine) ; break ; } case CRV_ARC : { PtrOwner pCrvArc( GetCurveArc( pCrv->Clone())) ; if ( IsNull( pCrvArc)) { delete onPolyCrv ; return false ; } ON_ArcCurve* onArcCrv = ConvertCrvArc( pCrvArc) ; if ( onArcCrv == nullptr) { delete onPolyCrv ; return false ; } onPolyCrv->Append( onArcCrv) ; break ; } case CRV_BEZIER : { PtrOwner pCrvBz( GetCurveBezier( pCrv->Clone())) ; if ( IsNull( pCrvBz)) { delete onPolyCrv ; return false ; } ON_NurbsCurve* onNurbsCrv = ConvertCrvBezier( pCrvBz) ; if ( onNurbsCrv == nullptr) { delete onPolyCrv ; return false ; } onPolyCrv->Append( onNurbsCrv) ; break ; } default : break ; } } // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onPolyCrv, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- ON_LineCurve* Export3dm::ConvertCrvLine( const ICurveLine* pCrvL) { Point3d ptStart, ptEnd ; pCrvL->GetStartPoint( ptStart) ; pCrvL->GetEndPoint( ptEnd) ; PtrOwner onCrvLine( new ON_LineCurve( ON_Line( ConvertPoint( ptStart), ConvertPoint( ptEnd)))) ; return Release( onCrvLine) ; } //---------------------------------------------------------------------------- bool Export3dm::ExportCrvLine( const string& sName, const IGdbIterator& iIter, const Frame3d& frFrame, const Color& cCol, const int& nLayer) { // recupero l'oggetto geometrico const IGeoObj* pGeoObj = iIter.GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // verifico oggetto PtrOwner pCrvL( GetCurveLine( pGeoObj->Clone())) ; if ( IsNull( pCrvL)) return false ; // lo porto nel frame globale pCrvL->ToGlob( frFrame) ; ON_LineCurve* onCrvLine = ConvertCrvLine( pCrvL) ; // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onCrvLine, nLayer, sName, cCol) ; } //---------------------------------------------------------------------------- bool Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer) { // 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, nLayer)) bOk = false ; } return bOk ; }