diff --git a/Import3dm.cpp b/Import3dm.cpp index 1304236..cbd82f2 100644 --- a/Import3dm.cpp +++ b/Import3dm.cpp @@ -39,8 +39,8 @@ #include "/EgtDev/Include/EGkExtText.h" #include "/EgtDev/Include/EGkExtDimension.h" #include "/EgtDev/Include/EGkVector3d.h" -//#include "C:/EgtDev/opennurbs/opennurbs.h" #include "/EgtDev/Extern/opennurbs/Include/opennurbs.h" +#include "/EgtDev/Include/EGkGeoObjSave.h" using namespace std ; @@ -974,8 +974,6 @@ Import3dm::ConvertSurface( const ON_Surface* onSurf) ON_NurbsSurface onNurbsSurface( *onNurbsSurface_) ; int nSpanU = onNurbsSurface.SpanCount(0); int nSpanV = onNurbsSurface.SpanCount(1); - //onNurbsSurface.MakeClampedUniformKnotVector( 0) ; // rende non periodico, ma non toglie i punti in più - //onNurbsSurface.MakeClampedUniformKnotVector( 1) ; SNurbsSurfData sNurbsSurf ; sNurbsSurf.bClosedU = onNurbsSurface.IsClosed( 0) ; sNurbsSurf.bClosedV = onNurbsSurface.IsClosed( 1) ; @@ -1215,6 +1213,12 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh ) 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 + // e applicando 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 + MakeUniform( &sfrTrim, onNurbsSurface, dScaleU, dScaleV) ; int nDegU, nDegV, nSpanU, nSpanV ; bool bRat, bTrim ; pSurfBezNew->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrim) ; @@ -1256,6 +1260,111 @@ Import3dm::ConvertBrep( const ON_Brep* onBrep, const bool bForceTriMesh ) return vSurf ; } +//---------------------------------------------------------------------------- +bool +Import3dm::MakeUniform( ISurfFlatRegion** sfr, ON_NurbsSurface onNurbsSurface, double& dScaleU, double& dScaleV) +{ + PtrOwner sfr_rescaled( CreateSurfFlatRegion()) ; + for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) { + // vettore dei nodi + DBLVECTOR vU ; + for ( int i = 0 ; i < onNurbsSurface.KnotCount( nDir) ; ++i ) { + vU.push_back( onNurbsSurface.Knot( nDir, i)) ; + } + int a = 0, b = 1 ; + double d0 = abs( vU[b] - vU[a]), d1 = d0, d00 = d0 ; + while ( b < (int)vU.size() && d1 < d0 + EPS_SMALL && d1 > d0 - EPS_SMALL) { + d0 = d1 ; + a = b ; + ++b ; + if ( b < (int)vU.size()) + d1 = abs( vU[b] - vU[a]) ; + } + sfr_rescaled.Set( CreateSurfFlatRegion()) ; + if ( IsNull( sfr_rescaled)) + return false ; + bool bDone = false ; + if ( b != (int)vU.size()) { + double dLenTot = vU.back() - vU.front() ; + for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) { + PtrOwner pSfr_copy( (*sfr)->Clone()) ; + if ( IsNull( pSfr_copy)) + return false ; + double dLenStrip = abs( vU[p+1] - vU[p]) ; + // creo la maschera per tagliare la superficie originale e ottenere una striscia + PtrOwner pSfrTrim( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrTrim)) + return false ; + if ( p != (int)vU.size() - 2) { + Vector3d vt ; + if ( nDir == 0) { + pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenTot - abs(vU[p+1]), dScaleV)) ; + vt.Set( abs(vU[p+1]), 0, 0) ; + } + else{ + pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU, dLenTot - abs(vU[p+1]))) ; + vt.Set( 0, abs(vU[p+1]), 0) ; + } + pSfrTrim->Translate( vt) ; + } + if ( p != 0 ) { + PtrOwner pSfrTrim1( CreateSurfFlatRegion()) ; + if ( nDir == 0) + pSfrTrim1.Set( GetSurfFlatRegionRectangle( abs(vU[p] - vU.front()), dScaleV)) ; + else + pSfrTrim1.Set( GetSurfFlatRegionRectangle( dScaleU, abs( vU[p] - vU.front()))) ; + if ( IsNull( pSfrTrim1)) + return false ; + if ( pSfrTrim->IsValid()) { + if ( ! pSfrTrim->Add( *pSfrTrim1)) + return false ; + } + else + pSfrTrim.Set( pSfrTrim1) ; + } + bDone = SaveGeoObj( pSfrTrim, "D:\\Temp\\trim.nge") ; + if ( ! pSfr_copy->Subtract( *pSfrTrim)) + return false ; + if ( nDir == 0) + pSfr_copy->Scale( GLOB_FRM, d00 / dLenStrip, 1, 1) ; + else + pSfr_copy->Scale( GLOB_FRM, 1, d00 / dLenStrip, 1) ; + bDone = SaveGeoObj( pSfr_copy, "D:\\Temp\\trimmed.nge") ; + if ( sfr_rescaled->IsValid()) { + // prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo + BBox3d bbSrf, bbSrf_copy ; + sfr_rescaled->GetLocalBBox( bbSrf) ; + pSfr_copy->GetLocalBBox( bbSrf_copy) ; + Vector3d vt ; + if ( nDir == 0) + vt.Set( bbSrf.GetMax().x - bbSrf_copy.GetMin().x, 0, 0) ; + else + vt.Set( 0, bbSrf.GetMax().y - bbSrf_copy.GetMin().y, 0) ; + pSfr_copy->Translate( vt) ; + if ( ! sfr_rescaled->Add( *pSfr_copy)) + return false ; + } + else + sfr_rescaled.Set( pSfr_copy) ; + bDone = SaveGeoObj( sfr_rescaled, "D:\\Temp\\scaled_additive.nge") ; + } + } + BBox3d bbSrf ; + sfr_rescaled->GetLocalBBox( bbSrf) ; + if ( nDir == 0) { + dScaleU = bbSrf.GetMax().x ; + *sfr = Release( sfr_rescaled) ; + } + else + dScaleV = bbSrf.GetMax().y ; + } + + *sfr = Release( sfr_rescaled) ; + + return true ; +} + +//---------------------------------------------------------------------------- ICurve* Import3dm::ConvertBrepLoop( const ON_BrepLoop* onBrepLoop) { diff --git a/Import3dm.h b/Import3dm.h index 21e5fe2..ef5e97a 100644 --- a/Import3dm.h +++ b/Import3dm.h @@ -28,11 +28,13 @@ class ON_Brep ; class ON_BrepLoop ; class ON_3dVector ; class ON_2dVector ; +class ON_NurbsSurface ; class ICurve ; class ICurveArc ; class ICurveLine ; class ISurf ; class ISurfTriMesh ; +class ISurfFlatRegion ; //---------------------------------------------------------------------------- class Import3dm : public IImport3dm @@ -53,6 +55,7 @@ private : ISurf* ConvertSurface( const ON_Surface* onSurf) ; ISURFPVECTOR 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) ; private : IGeomDB* m_pGDB ;