diff --git a/CurveAux.cpp b/CurveAux.cpp index 56a9448..dc6fba1 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -136,5 +136,182 @@ ArcToBezierCurve( const ICurve* pCrv, ICurve*& pCrvNew) pCrvNew = Release( pCrvCompo) ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +NurbsCurveCanonicalize( CNurbsData& cnData) +{ + // se periodica + if ( cnData.bPeriodic) { + // va trasformata in non-periodica (clamped) + // vedere The NurbsBook di Les Piegl e Tiller + // mancano esempi per testare + return false ; + } + // se con nodi extra + if ( cnData.bExtraKnotes) { + int nKnotesNbr = int( cnData.vU.size()) ; + if ( nKnotesNbr < 4) + return false ; + cnData.bExtraKnotes = false ; + for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i) + cnData.vU[i] = cnData.vU[i+1] ; + cnData.vU.resize( nKnotesNbr - 2) ; + return true ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +NurbsToBezierCurve( const CNurbsData& cnData, ICurve*& pCrvNew) +{ + // la curva Nurbs deve essere in forma canonica + if ( cnData.bPeriodic || cnData.bExtraKnotes) + return false ; + // numero dei nodi + int nU = int( cnData.vCP.size()) + cnData.nDeg - 1 ; + // controllo relazione nodi - punti di controllo + if ( nU != int( cnData.vU.size())) + return false ; + // numero degli intervalli + int nInt = nU - 2 * cnData.nDeg + 1 ; + + // se 1 solo intervallo, la Nurbs è già una curva di Bezier + if ( nInt == 1) { + // creo la curva di Bezier + PtrOwner pCrvBez( CreateCurveBezier()) ; + if ( ! IsValid( pCrvBez)) + return false ; + // la inizializzo + if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat)) + return false ; + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + if ( ! cnData.bRat) { + if ( ! pCrvBez->SetControlPoint( i, cnData.vCP[i])) + return false ; + } + else { + if ( ! pCrvBez->SetControlPoint( i, cnData.vCP[i], cnData.vW[i])) + return false ; + } + } + // restituisco la curva + pCrvNew = Release( pCrvBez) ; + return true ; + } + + // altrimenti è equivalente ad una curva composita, la creo + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( ! IsValid( pCrvCompo)) + return false ; + + // vettore dei punti di controllo della curva di Bezier + PNTVECTOR vBC ; + vBC.resize( cnData.nDeg + 1) ; + DBLVECTOR vBW ; + vBW.resize( cnData.nDeg + 1) ; + if ( ! cnData.bRat) { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) + vBC[i] = cnData.vCP[i] ; + } + else { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + vBC[i] = cnData.vCP[i] * cnData.vW[i] ; + vBW[i] = cnData.vW[i] ; + } + } + // primi coefficienti della successiva + PNTVECTOR vNextBC ; + vNextBC.resize( cnData.nDeg - 1) ; + DBLVECTOR vNextBW ; + vNextBW.resize( cnData.nDeg - 1) ; + // ... + DBLVECTOR vAlfa ; + vAlfa.resize( cnData.nDeg - 1) ; + int a = cnData.nDeg - 1 ; + int b = cnData.nDeg ; + // ciclo + while ( b < nU - 1) { + int i = b ; + while ( b < nU - 1 && fabs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO) + ++ b ; + int mult = std::min( b - i + 1, cnData.nDeg) ; + if ( mult < cnData.nDeg) { + // numeratore di alfa + double numer = cnData.vU[b] - cnData.vU[a] ; + // calcola e salva gli alfa + for ( int j = cnData.nDeg ; j > mult ; -- j) + vAlfa[j-mult-1] = numer / ( cnData.vU[a+j] - cnData.vU[a]) ; + // inserisco il nodo r volte + int r = cnData.nDeg - mult ; + for ( int j = 1 ; j <= r ; ++ j) { + int save = r - j ; + int s = mult + j ; + for ( int k = cnData.nDeg ; k >= s ; -- k) + vBC[k] = vAlfa[k-s] * vBC[k] + ( 1 - vAlfa[k-s]) * vBC[k-1] ; + if ( cnData.bRat) { + for ( int k = cnData.nDeg ; k >= s ; -- k) + vBW[k] = vAlfa[k-s] * vBW[k] + ( 1 - vAlfa[k-s]) * vBW[k-1] ; + } + if ( b < nU - 1) { + vNextBC[save] = vBC[cnData.nDeg] ; + if ( cnData.bRat) + vNextBW[save] = vBW[cnData.nDeg] ; + } + } + } + + // costruisco la curva di Bezier e la inserisco nella curva composita + PtrOwner pCrvBez( CreateCurveBezier()) ; + if ( ! IsValid( pCrvBez)) + return false ; + // la inizializzo + if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat)) + return false ; + if ( ! cnData.bRat) { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + if ( ! pCrvBez->SetControlPoint( i, vBC[i])) + return false ; + } + } + else { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i])) + return false ; + } + } + // la aggiungo alla curva composita + if ( ! pCrvCompo->AddCurve( Release( pCrvBez))) + return false ; + + // inizializzazioni per la prossima curva di Bezier + if ( b < nU - 1) { + if ( ! cnData.bRat) { + for ( int i = 0 ; i < cnData.nDeg - 1 ; ++ i) + vBC[i] = vNextBC[i] ; + for ( int i = cnData.nDeg - mult ; i <= cnData.nDeg ; ++ i) + vBC[i] = cnData.vCP[b-cnData.nDeg+i+1] ; + } + else { + for ( int i = 0 ; i < cnData.nDeg - 1 ; ++ i) { + vBC[i] = vNextBC[i] ; + vBW[i] = vNextBW[i] ; + } + for ( int i = cnData.nDeg - mult ; i <= cnData.nDeg ; ++ i) { + vBC[i] = cnData.vCP[b-cnData.nDeg+i+1] * cnData.vW[b-cnData.nDeg+i+1] ; + vBW[i] = cnData.vW[b-cnData.nDeg+i+1] ; + } + } + a = b ; + ++ b ; + } + } + + // restituisco la curva composita + pCrvNew = Release( pCrvCompo) ; return true ; } \ No newline at end of file diff --git a/CurveAux.h b/CurveAux.h index 0caf30e..5e6219a 100644 --- a/CurveAux.h +++ b/CurveAux.h @@ -13,14 +13,10 @@ #pragma once -#include "/EgtDev/Include/EGkCurve.h" +#include "/EgtDev/Include/EgkCurveAux.h" //---------------------------------------------------------------------------- bool IsClosed( const ICurve& crvC) ; bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ; bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ; bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ; - -//---------------------------------------------------------------------------- -// trasforma un arco in una curva di Bezier semplice o composta -bool ArcToBezierCurve( const ICurve* pArc, ICurve*& pCrvNew) ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 82ec3a5..abea144 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index e4059da..f4633cd 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -278,6 +278,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index cef2e26..eeaf350 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -407,6 +407,9 @@ File di intestazione + + File di intestazione +