diff --git a/Export3dm.cpp b/Export3dm.cpp index ec0c7d9..81ab095 100644 --- a/Export3dm.cpp +++ b/Export3dm.cpp @@ -115,10 +115,11 @@ Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile) return false ; pIter->GoTo( nId) ; // esporto l'oggetto e i suoi eventuali figli - bool bOk = ExportObject( *pIter, 0) ; + bool bAdded = false ; + bool bOk = ExportObject( *pIter, 0, bAdded) ; // stampo il file - int version = 7 ; + int version = 8 ; // errors printed to stdout ON_TextLog error_log ; // writes model to archive @@ -131,7 +132,7 @@ Export3dm::Export( IGeomDB* pGDB, int nId, const string& sFile) //---------------------------------------------------------------------------- bool -Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer) +Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer, bool& bAdded) { // recupero il livello dell'oggetto int nLev = GDB_LV_USER ; @@ -164,36 +165,50 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer) case GEO_PNT3D: { if ( ! ExportPnt( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } case SRF_BEZIER: { if ( ! ExportSrfBz( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } case SRF_FLATRGN : case SRF_TRIMESH : if ( ! ExportSTM( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; case CRV_ARC : { if ( ! ExportCrvArc( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } case CRV_BEZIER : { if ( ! ExportCrvBezier( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } case CRV_COMPO : { if ( ! ExportCrvCompo( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } case CRV_LINE : { if ( ! ExportCrvLine( sName, iIter, frFrame, cCol, nLayer)) return false ; + else + bAdded = true ; break ; } default : @@ -205,7 +220,8 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer) int nLayer = iIter.GetId() ; if ( nLayer == 0) { m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, m_model.LayerFromIndex( 0).ModelComponentId()) ; - return ScanGroup( iIter, nLayer) ; + bool bEmpty = false ; + return ScanGroup( iIter, nLayer, bEmpty) ; } // creo il layer e setto le proprietà ON_Layer* layer = new ON_Layer() ; @@ -236,11 +252,19 @@ Export3dm::ExportObject( const IGdbIterator& iIter, const int& nLayer) // aggiungo il layer ON_ModelComponentReference mcr = m_model.AddManagedModelComponent( layer) ; + ON_UUID uuid = mcr.ModelComponentId() ; int nIndex = mcr.ModelComponentIndex() ; m_mLayer.insert( pair< int, int>( nLayer, nIndex)) ; - + // esploro il gruppo - return ScanGroup( iIter, nIndex) ; + bool bEmpty = false ; + bool bOk = ScanGroup( iIter, nIndex, bEmpty) ; + if ( bEmpty) + ; + //m_model.RemoveModelComponent( ON_ModelComponent::Type::Layer, uuid) ; // se si volessero cancellare i layer vuoti + else + bAdded = true ; + return bOk ; } default : return false ; @@ -434,10 +458,10 @@ Export3dm::ExportSrfBz( const string& sName, const IGdbIterator& iIter, const Fr // imposto il vettore dei nodi in V int nKnotCountV = nDegV + nCPV - 1 ; dKnot = 0 ; - // per costruzione nKnotCount é un multiplo di nDegU + // per costruzione nKnotCount é un multiplo di nDegV for ( int v = 0 ; v < int ( nKnotCountV / nDegV) ; ++v) { for ( int p = 0 ; p < nDegV ; ++p) - onNurbsSurf->SetKnot( 0, v * nDegV + p, dKnot) ; + onNurbsSurf->SetKnot( 1, v * nDegV + p, dKnot) ; ++dKnot ; } // aggiungo l'oggetto al modello @@ -482,6 +506,11 @@ Export3dm::ExportSTM( const string& sName, const IGdbIterator& iIter, const Fram int nIdVert[3] ; pSrfTm->GetTriangle( t, nIdVert) ; onMesh->SetTriangle( t, nIdVert[0], nIdVert[1], nIdVert[2]) ; } + ON_MeshVertexFaceMap onMeshVertMap ; + onMeshVertMap.SetFromMesh( onMesh, false) ; + onMesh->AddPlanarNgons( onMeshVertMap.VertexFaceMap(), 0.1, 3, 1, true) ; + onMesh->ComputeFaceNormals() ; + onMesh->Compact() ; // aggiungo l'oggetto al modello return AddObjectToModel( iIter, onMesh, nLayer, sName, cCol) ; } @@ -689,7 +718,7 @@ Export3dm::ExportCrvLine( const string& sName, const IGdbIterator& iIter, const //---------------------------------------------------------------------------- bool -Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer) +Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer, bool& bEmpty) { // creo un iteratore PtrOwner pIter( CreateGdbIterator( iIter.GetGDB())) ; @@ -697,12 +726,19 @@ Export3dm::ScanGroup( const IGdbIterator& iIter, const int& nLayer) return false ; // scandisco il gruppo bool bOk = true ; + int nCount = 0 ; for ( bool bNext = pIter->GoToFirstInGroup( iIter) ; bNext ; bNext = pIter->GoToNext()) { - if ( ! ExportObject( *pIter, nLayer)) + bool bAdded = false ; + if ( ! ExportObject( *pIter, nLayer, bAdded)) bOk = false ; + else if ( bAdded) + ++ nCount ; } + if ( nCount == 0) + bEmpty = true ; + return bOk ; } diff --git a/Export3dm.h b/Export3dm.h index 0f4ddf8..56b0925 100644 --- a/Export3dm.h +++ b/Export3dm.h @@ -41,11 +41,11 @@ class Export3dm : public IExport3dm } private : - bool ExportObject( const IGdbIterator& iIter, const int& nLayer) ; + bool ExportObject( const IGdbIterator& iIter, const int& nLayer, bool& bAdded) ; bool AddObjectToModel( const IGdbIterator& iIter, ON_Object* onObject, const int& nLayer, const std::string& sName, const Color& cCol, ON_3dmObjectAttributes* pOnAttr = nullptr) ; bool AddInfoToObject( const IGdbIterator& iIter, ON_Object* onObject) ; - bool ScanGroup( const IGdbIterator& iIter, const int& nLayer) ; + bool ScanGroup( const IGdbIterator& iIter, const int& nLayer, bool& bEmpty) ; // nCount restituisce il numero di oggetti inseriti nel gruppo bool TestFilter( int nLev, int nMode, int nStat, bool bGroup = false) ; std::wstring ConvertString( const std::string& sName) { return std::wstring( sName.begin(), sName.end()) ;} ; ON_3dPoint ConvertPoint( const Point3d& pt) { return ON_3dPoint( pt.x, pt.y, pt.z) ;} ; diff --git a/Import3dm.cpp b/Import3dm.cpp index b90c85a..55dea22 100644 --- a/Import3dm.cpp +++ b/Import3dm.cpp @@ -102,7 +102,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, int nFirstId = 0 ; ON_UUID ON_nil_uuid = { 0,0,0,{ 0,0,0,0,0,0,0,0}} ; - int nLayDelCount = 0 ; + //int nLayDelCount = 0 ; //serve solo se si vogliono cancellare i layer parent. Se però questi layer contengono oggetti, che non sono in sottolayer del parent, non verranno visualizzati for ( const ON_ModelComponent* mc = component_iterator_l.FirstComponent() ; mc != nullptr ; mc = component_iterator_l.NextComponent()) { ON_UUID uuid = mc->Id() ; const ON_Layer* onLayer = ON_Layer::Cast( mc) ; @@ -125,18 +125,21 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, [uuidParent](pair< int, tuple> x){ return !ON_UuidCompare( get<1>(get<1>(x)), uuidParent) ;}); } - // se era già stato aggiunto il parent e non era già indicata la presenza di sottolayer - // devo eliminare il parent e mettere a true il flag dei sottolayer nella mappa dei layer - if ( it_parent != m_mLayer.end() ) { - if ( !get<3>(it_parent->second) ) { - get<3>(it_parent->second) = true ; - m_pGDB->Erase( it_parent->first) ; - auto LayerDeleted = m_mLayer.extract(it_parent->first); - LayerDeleted.key() = nLayDelCount ; - -- nLayDelCount ; - m_mLayer.insert(std::move(LayerDeleted)); - } - } + + // COMMENTO QUESTO TRATTO PERCHé, LASCIO I LAYER PARENT E LI CANCELLO ALLA FINE DELL'IMPORT SOLO SE RESTANO VUOTI + // + //// se era già stato aggiunto il parent e non era già indicata la presenza di sottolayer + //// devo eliminare il parent e mettere a true il flag dei sottolayer nella mappa dei layer + // if ( it_parent != m_mLayer.end() ) { + // if ( !get<3>(it_parent->second) ) { + // get<3>(it_parent->second) = true ; + // m_pGDB->Erase( it_parent->first) ; + // auto LayerDeleted = m_mLayer.extract(it_parent->first); + // LayerDeleted.key() = nLayDelCount ; + // -- nLayDelCount ; + // m_mLayer.insert(std::move(LayerDeleted)); + // } + // } int nIdLayer = m_pGDB->AddGroup( GDB_ID_NULL, nIdGroup, GLOB_FRM) ; if ( nFirstId == 0) @@ -151,9 +154,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, // se non riesco a convertire un oggetto, lo scarto e incremento il contatore del suo tipo nel dizionario error_count int nId ; - int nCount = 0 ; for( const ON_ModelComponent* mc = component_iterator.FirstComponent() ; mc != nullptr ; mc = component_iterator.NextComponent()) { - ++ nCount ; const ON_ModelGeometryComponent* mgc = ON_ModelGeometryComponent::Cast( mc) ; const ON_Object* oGeometry = mgc->Geometry( nullptr) ; // individuo a che layer appartiene l'oggetto @@ -327,6 +328,7 @@ Import3dm::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, } } + // CANCELLO I LAYER RIMASTI VUOTI ?? // messaggio di errore da mettere nel log per dire quanti oggetti sono stati ignorati perché la conversione non è riuscita map::iterator it = m_mError_count.begin() ; @@ -456,7 +458,7 @@ Import3dm::ConvertCurve( const ON_Curve* onCurve) } case ON::eCurveType::ctProxy :{ const ON_CurveProxy* onProxyCurve = ON_CurveProxy::Cast( onCurve) ; - ON_Curve* onCurve = onProxyCurve->DuplicateCurve() ; + const ON_Curve* onCurve = onProxyCurve->ProxyCurve() ; return ConvertCurve( onCurve) ; break ; } @@ -631,9 +633,13 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf) // uso la nurbs form ON_NurbsSurface onNurbsSurface ; int nOk = onBrepFace->GetNurbForm( onNurbsSurface) ; - if ( nOk != 0) + + if ( nOk != 0){ pSurf.Set( ConvertSurface( & onNurbsSurface)) ; + } else { + // QUI PERò NON TENGO CONTO DEL TRIM!!!!!! + // // se non è riuscita la conversione in nurbs tengo la superficie originale const ON_Surface* onSurfFace = onBrepFace->ProxySurface() ; // qui devo applicare a mano le trasformazioni dalla superfice originale alla proxy @@ -649,7 +655,7 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf) pSurf.Set( ConvertSurface( &onNurbsSurface)) ; } else - pSurf.Set( ConvertSurface( onSurfaceProxy->DuplicateSurface())) ; + pSurf.Set( ConvertSurface( onSurfaceProxy->ProxySurface())) ; return Release( pSurf) ; } @@ -670,10 +676,11 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh) if ( ! stmSoup.Start()) return vSurf ; bool bSurfTm = false ; - int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0 ; + int nFailedBFace = 0, nFailedTm = 0, nFailedFr = 0, nFailedBz = 0, nFailedBTrim = 0 ; for ( int i = 0 ; i < onBrep->m_F.Count() ; ++i) { ON_BrepFace* onFace = onBrep->Face( i) ; + bool bRev = onFace->m_bRev ; const ON_Surface* onSurface = onFace->SurfaceOf() ; PtrOwner pSurf ; if ( const ON_PlaneSurface* onPlaneSurface = ON_PlaneSurface::Cast( onSurface)) { @@ -706,61 +713,93 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh) if ( nType == SRF_TRIMESH) { bSurfTm = true ; PtrOwner pSurfTm( GetSurfTriMesh( Release( pSurf))) ; - if ( ! IsNull( pSurfTm) && pSurfTm->IsValid()) + if ( !IsNull(pSurfTm) && pSurfTm->IsValid() ) { + if ( bRev) + pSurfTm->Invert() ; stmSoup.AddSurfTriMesh( *pSurfTm) ; + } else ++ nFailedTm ; } else if ( nType == SRF_FLATRGN) { bSurfTm = true ; PtrOwner pSurfFr( GetSurfFlatRegion( Release( pSurf))) ; - if ( ! IsNull( pSurfFr) && pSurfFr->IsValid()) - stmSoup.AddSurfTriMesh( *pSurfFr->GetAuxSurf()) ; + if ( ! IsNull( pSurfFr) && pSurfFr->IsValid()) { + if ( bRev) + pSurfFr->Invert() ; + stmSoup.AddSurfTriMesh(*pSurfFr->GetAuxSurf()) ; + } else ++ nFailedFr ; } else if ( nType == SRF_BEZIER) { PtrOwner pSurfBezNew( GetSurfBezier( Release( pSurf))) ; - // se ho più di un loop vuol dire che ho dei trim sulla faccia e quindi li aggiungo alla superficie di bezier - // prima della triangolazione if ( ! IsNull( pSurfBezNew) && pSurfBezNew->IsValid()) { ON_BrepFace* onFace = onBrep->Face( i) ; SurfFlatRegionByContours SfrCntr ; - for ( int k = 0 ; k < onFace->LoopCount() ; ++k ) - SfrCntr.AddCurve( ConvertBrepLoop( onFace->Loop( k))) ; - + const ON_Surface* onSurface = onFace->SurfaceOf() ; + // se la superficie era una superficie di rivoluzione, le eventuali curve di trim erano parametrizzate con la coordinata x in radianti, + // e non riferita allo spazio parametrico della nurbs corrispondente ( che sarebbe una nurbs razionale, dovendo approssimare un arco di circonferenza) + // devo quindi prelevare le curve di trim e cambiarne le coordinate per matcharle allo spazio parametrico della nurbs + if ( const ON_RevSurface* onRevSurf = ON_RevSurface::Cast( onSurface) ) { + for ( int k = 0 ; k < onFace->LoopCount() ; ++k ) { + ICurve* pCrv( ConvertBrepLoop( onFace->Loop( k))) ; + // qui devo spostare ogni punto della curva dallo spazio parametrico della superificie rev allo spazio della superficie nurbs + ConvertCurveParam( onRevSurf, &pCrv) ; + pCrv->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ; + SfrCntr.AddCurve( pCrv) ; + } + } + else { + for ( int k = 0 ; k < onFace->LoopCount() ; ++k ) { + PtrOwner pCrv( ConvertBrepLoop( onFace->Loop( k))) ; + pCrv->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ; + SfrCntr.AddCurve( Release( pCrv)) ; + } + } ISurfFlatRegion* sfrTrim = SfrCntr.GetSurf() ; - // questa regione di Trim deve essere riferita al rettangolo parametrico totale ( spaz param 1x1 -> regione trim 1000x1000) - // devo anche controllare che il sistema di riferimento dello spazio di trim totale sia giusto ( con l'angolo BottomLeft in (0,0) - //posizonato nel primo quadrante del piano XY) + + // questa regione di Trim deve essere riferita al rettangolo parametrico totale ( spaz param 1x1 -> regione trim 1000x1000) + // devo anche controllare che il sistema di riferimento dello spazio di trim totale sia giusto ( con l'angolo BottomLeft in (0,0) + //posizonato nel primo quadrante del piano XY) double u0,u1,v0,v1 ; onFace->GetDomain(0, &u0, &u1) ; onFace->GetDomain(1, &v0, &v1) ; double dScaleU = u1 - u0 ; double dScaleV = v1 - v0 ; - Vector3d vToOrig( -u0, -v0, 0) ; - sfrTrim->Translate( vToOrig) ; - // se la superficie di partenza aveva vettori dei nodi non uniformi devo riscalare lo spazio parametrico in modo da renderli uniformi - // applicando così la trasformazione anche alle curve di trim. + + Vector3d vToOrig( -u0 * SBZ_TREG_COEFF, -v0 * SBZ_TREG_COEFF, 0) ; + if ( sfrTrim != nullptr) + sfrTrim->Translate( vToOrig) ; + else { + ++ nFailedBTrim ; + return vSurf ; + } + // se la superficie di partenza aveva vettori dei nodi non uniformi devo riscalare lo spazio parametrico in modo da renderli uniformi + // applicando così la trasformazione anche alle curve di trim. ON_NurbsSurface onNurbsSurface ; onFace->GetNurbForm( onNurbsSurface) ; - // rendo uniforme lo spazio parametrico nella direzione dei parametri che non lo sono + // rendo uniforme lo spazio parametrico nella direzione dei parametri che non lo sono int nDegU, nDegV, nSpanU, nSpanV ; bool bRat, bTrim ; pSurfBezNew->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrim) ; - // devo rendere lo spazio parametrico uniforme solo se la superficie è trimmata, sennò non serve - // per capire se la superficie sia trimmata controllo che lo spazio parametrico trimmato non coincida con tutto lo spazio parametrico - PtrOwner pSurfParam( GetSurfFlatRegionRectangle( dScaleU - EPS_SMALL, dScaleV - EPS_SMALL)) ; - pSurfParam->Subtract( *sfrTrim) ; - if ( pSurfParam->IsValid()) + // devo rendere lo spazio parametrico uniforme solo se la superficie è trimmata, sennò non serve + // per capire se la superficie sia trimmata controllo che lo spazio parametrico trimmato non coincida con tutto lo spazio parametrico + PtrOwner pSurfParam(GetSurfFlatRegionRectangle(( dScaleU - EPS_SMALL ) * SBZ_TREG_COEFF, ( dScaleV - EPS_SMALL) * SBZ_TREG_COEFF)) ; + // se la sottrazione tra spazio parametrico e superficie di trim è diversa da zero, allora la superficie era trimmata + if ( sfrTrim != nullptr && pSurfParam->Subtract( *sfrTrim) && pSurfParam->IsValid()) { MakeUniform( &sfrTrim, onNurbsSurface, dScaleU, dScaleV) ; + pSurfBezNew->SetTrimRegion( *sfrTrim) ; + } else - sfrTrim->Scale( GLOB_FRM, nSpanU * SBZ_TREG_COEFF / dScaleU, nSpanV * SBZ_TREG_COEFF / dScaleV, 1) ; - pSurfBezNew->SetTrimRegion( *sfrTrim) ; + sfrTrim->Scale( GLOB_FRM, nSpanU / dScaleU, nSpanV / dScaleV, 1) ; if ( sfrTrim != nullptr) delete sfrTrim ; + if ( bRev) + pSurfBezNew->Invert() ; + if ( ! bForceTriMesh) vSurf.emplace_back( Release( pSurfBezNew)) ; else @@ -789,6 +828,10 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh) string sOut = "Import3dm : Failed conversion of " + to_string( nFailedBz) + " NURBS belonging to a Brep" ; LOG_ERROR( GetEE3Logger(), sOut.c_str()) ; } + if ( nFailedBTrim != 0) { + string sOut = "Import3dm : Failed conversion of " + to_string( nFailedBTrim) + " trims of surfaces belonging to a Brep" ; + LOG_ERROR( GetEE3Logger(), sOut.c_str()) ; + } if ( ! stmSoup.End()) return vSurf ; @@ -803,7 +846,8 @@ bool Import3dm::MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double dScaleU, double dScaleV) { // riscalo le superfici prima di effettuare una serie di operazioni di collage - (*sfr)->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ; + //(*sfr)->Scale( GLOB_FRM, SBZ_TREG_COEFF, SBZ_TREG_COEFF, 1) ; + // la superficie in input arriva già scalata bool bRescaledU = false ; bool bRescaledV = false ; int nSpanU = 1, nSpanV = 1 ; @@ -928,8 +972,24 @@ Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop) for ( int i = 0 ; i < nTrim ; ++i) { ON_BrepTrim* onBrepTrim = onBrepLoop->Trim( i) ; ON_CurveProxy* onCurveProxy = ON_CurveProxy::Cast( onBrepTrim); - pCrvCompo->AddCurve( ConvertCurve( onCurveProxy)) ; + PtrOwner pCrv( ConvertCurve( onCurveProxy)) ; + if ( ! pCrvCompo->AddCurve( pCrv->Clone())) { + Point3d ptEnd ; pCrvCompo->GetEndPoint( ptEnd) ; + pCrv->ModifyStart( ptEnd) ; + if ( ! pCrvCompo->AddCurve( pCrv->Clone())) + return nullptr ; + } } + + //// APPROSSIMO I BREP LOOP PER ALLEGGERIRE LE OPERAZIONI DI TRIM DELLE BEZIER + //pCrvCompo->RemoveSmallParts( 0.1, 15) ; + //pCrvCompo->MergeCurves( 0.1, 15) ; + + + //PolyArc paApprox ; + //pCrvCompo->ApproxWithArcs( 0.1, 15, paApprox) ; + //pCrvCompo->FromPolyArc( paApprox) ; + return Release( pCrvCompo) ; } @@ -1046,7 +1106,6 @@ Import3dm::ConvertExtrusion( const ON_Extrusion* onExtrusion) ISurfTriMesh* Import3dm::ConvertMesh( const ON_Mesh* onMesh) { - ON_Mesh* onMeshToConvert = onMesh->Duplicate() ; PtrOwner pSurfTm( CreateSurfTriMesh()) ; if ( IsNull( pSurfTm)) @@ -1106,6 +1165,9 @@ Import3dm::ConvertMesh( const ON_Mesh* onMesh) } } } + + delete onMeshToConvert ; + pSurfTm->AdjustTopology() ; return Release( pSurfTm) ; } @@ -1304,3 +1366,69 @@ Import3dm::ConvertAnnotation( const ON_Annotation* onAnnot, const ON_DimStyle* o m_mError_count["annotation"] += 1 ; return vpObj ; } + +//---------------------------------------------------------------------------- +bool +Import3dm::ConvertCurveParam( const ON_RevSurface* onRevSurf, ICurve** pCrv) +{ + PtrOwner pCrvNew ; + if ( (*pCrv)->GetType() == CRV_LINE) { + PtrOwner pCrvLine( CreateCurveLine()) ; + double dnurbsU ; + double dnurbsV ; + Point3d ptStart ; (*pCrv)->GetStartPoint( ptStart) ; + onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptStart.x, ptStart.y, &dnurbsU, &dnurbsV) ; + ptStart.Set( dnurbsU, dnurbsV, 0) ; + Point3d ptEnd ; (*pCrv)->GetEndPoint( ptEnd) ; + onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptEnd.x, ptEnd.y, &dnurbsU, &dnurbsV) ; + ptEnd.Set( dnurbsU, dnurbsV, 0) ; + pCrvLine->Set( ptStart, ptEnd) ; + pCrvNew.Set( Release( pCrvLine)) ; + } + else if ( (*pCrv)->GetType() == CRV_ARC) { + double dnurbsU ; + double dnurbsV ; + Point3d ptStart ; (*pCrv)->GetStartPoint( ptStart) ; + onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptStart.x, ptStart.y, &dnurbsU, &dnurbsV) ; + ptStart.Set( dnurbsU, dnurbsV, 0) ; + Point3d ptEnd ; (*pCrv)->GetEndPoint( ptEnd) ; + onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptEnd.x, ptEnd.y, &dnurbsU, &dnurbsV) ; + ptEnd.Set( dnurbsU, dnurbsV, 0) ; + Vector3d vtDir, vtN ; + (*pCrv)->GetStartDir( vtDir) ; + ICurveArc* pCrvArcOrig = GetCurveArc( (*pCrv)) ; + vtN = pCrvArcOrig->GetNormVersor( ) ; + PtrOwner pCrvArc( CreateCurveArc()) ; + pCrvArc->Set2PVN( ptStart, ptEnd, vtDir, vtN) ; + pCrvNew.Set( Release( pCrvArc)) ; + } + else if ( (*pCrv)->GetType() == CRV_BEZIER) { + double dnurbsU ; + double dnurbsV ; + PtrOwner pCrvBez( GetCurveBezier( (*pCrv))) ; + int nDeg = pCrvBez->GetDegree() ; + int nCV = nDeg + 1 ; + for ( int i = 0 ; i < nCV ; ++i) { + Point3d ptNew = pCrvBez->GetControlPoint( i) ; + onRevSurf->GetNurbFormParameterFromSurfaceParameter( ptNew.x, ptNew.y, &dnurbsU, &dnurbsV) ; + ptNew.Set( dnurbsU, dnurbsV, 0) ; + // sto cambiando le coordinate dei CP nella curva, mentre i pesi non sono da modificare + pCrvBez->SetControlPoint( i, ptNew) ; + } + pCrvNew.Set( pCrvBez) ; + } + else if ( (*pCrv)->GetType() == CRV_COMPO) { + PtrOwner pCrvCompo( GetCurveComposite( (*pCrv))) ; + PtrOwner pCrvCompoNew( CreateCurveComposite()) ; + for ( const ICurve* pCrvSimpleOrig = pCrvCompo->GetFirstCurve() ; pCrvSimpleOrig != nullptr ; pCrvSimpleOrig = pCrvCompo->GetNextCurve()) { + ICurve* pCrvSimple( pCrvSimpleOrig->Clone()) ; + ConvertCurveParam( onRevSurf, &pCrvSimple) ; + pCrvCompoNew->AddCurve( pCrvSimple) ; + } + pCrvNew.Set( pCrvCompoNew) ; + } + + (*pCrv) = Release( pCrvNew) ; + + return true ; +} diff --git a/Import3dm.h b/Import3dm.h index 27fe6b3..85cc35b 100644 --- a/Import3dm.h +++ b/Import3dm.h @@ -53,6 +53,7 @@ class Import3dm : public IImport3dm ISURFPOVECTOR ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh) ; ICurve* ConvertBrepLoop( const ON_BrepLoop* onBrepLoop) ; bool MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double dScaleU, double dScaleV) ; + bool ConvertCurveParam( const ON_RevSurface* onRevSurf, ICurve** pCrv) ; private : IGeomDB* m_pGDB ;