From 381a137604b494aa71c4aab6ee9391c1aa73dcce Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 21 Sep 2023 14:38:22 +0200 Subject: [PATCH] EgtGeomKernel : - introduzione delle nurbs periodiche; da finire. --- CurveAux.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 9 deletions(-) diff --git a/CurveAux.cpp b/CurveAux.cpp index 795c6e4..7a7d0e2 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -510,14 +510,7 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg) 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 + // se con nodi extra if ( cnData.bExtraKnotes) { int nKnotesNbr = int( cnData.vU.size()) ; if ( nKnotesNbr < 4) @@ -526,7 +519,91 @@ NurbsCurveCanonicalize( CNurbsData& cnData) for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i) cnData.vU[i] = cnData.vU[i+1] ; cnData.vU.resize( nKnotesNbr - 2) ; - return true ; + } + + // se periodica + if ( cnData.bPeriodic) { + CNurbsData cnData_clamped ; + // va trasformata in non-periodica (clamped) + // bisogna aumentare la molteplicitą del primo e ultimo nodo fino ad arrivare al grado della nurbs + // e poi scartare nodi e punti fuori dalla regione clamped ( tra u_p e u_(m-p) ?) + + // comincio ad aumentare la molteplictią della fine della curva + int nCP = int( cnData.vCP.size()) ; + int nU = nCP + cnData.nDeg - 1 ; + 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[ cnData.nDeg - i] = cnData.vCP[nCP - 1 - i] ; + } + else { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + vBC[cnData.nDeg - i] = cnData.vCP[nCP - i] * cnData.vW[nCP - i] ; + vBW[cnData.nDeg - i] = cnData.vW[nCP - i] ; + } + } + + + double alpha ; + int b = nU - 1 ; + int a = b - 1 ; + int i = b ; + while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO) + -- b ; + int mult = min( i - b + 1, cnData.nDeg) ; // mi aspetto che sia 1, ma comunque sarą < cnData.nDeg + int r = cnData.nDeg - mult ; + //// indice che si riferisce al vettore vCP + int c = nU - cnData.nDeg + 1 ; + // aggiusto a mano il vettore dei nodi ( aumento la molteplicitą del primo valore fino a cnData.nDeg) + double dKnot = cnData.vU[ nU - 1] ; + cnData.vU.resize( nU + r) ; + for ( int t = 0 ; t < r ; ++t) { + cnData.vU[nU + t] = dKnot ; + } + + if ( mult < cnData.nDeg) { + // inserisco il nodo r volte + for ( int j = 1 ; j <= r ; ++ j) { + int L = b - cnData.nDeg + j ; + for ( int i = 0; i <= r - j ; ++i) { + alpha = (cnData.vU[b] - cnData.vU[L+i])/ ( cnData.vU[i+b+1] - cnData.vU[L+i]) ; + vBC[i] = alpha * vBC[i+1] + ( 1 - alpha) * vBC[i] ; + if ( cnData.bRat) { + vBW[i] = alpha * vBW[i+1] + ( 1 - alpha) * vBW[i] ; + } + } + cnData.vCP[L] = vBC[0] ; + //cnData.vCP[c+r-j-mult] = vBC[r-j] ; + if ( cnData.bRat ) { + cnData.vW[L] = vBW[0] ; + //cnData.vW[c+r-j-mult] = vBW[r-j] ; + } + } + } + // aggiungo i punti ottenuti alla curva. + cnData.vCP.resize( nCP + cnData.nDeg - mult) ; + for ( int p = 0 ; p < cnData.nDeg - mult ; ++p) { + cnData.vCP[ nCP + cnData.nDeg - mult - 1 - p] = vBC[cnData.nDeg - p] ; + } + if ( cnData.bRat ) { + cnData.vW.resize( nCP + cnData.nDeg - mult) ; + for ( int p = 0 ; p <= cnData.nDeg ; ++p) { + cnData.vW[ nCP + cnData.nDeg - mult - 1 - p] = vBW[cnData.nDeg - p] ; + } + } + + // aumento la molteplicitą del primo punto + + // aggiusto a mano il vettore dei nodi ( aumento la molteplicitą del primo valore fino a cnData.nDeg) + /// DA ADATTARE PER IL PRIMO + cnData.vU.resize( nU + cnData.nDeg - mult) ; + dKnot = cnData.vU[ nU] ; + for ( int t = nU - 1 ; t < cnData.nDeg - mult - 1 ; ++t) { + cnData.vU[t] = dKnot ; + } } return true ; @@ -710,6 +787,30 @@ NurbsToBezierCurve( const CNurbsData& cnData) } } + // se la curva ha grado 1, manca da aggiungere l'ultimo tratto + if ( cnData.nDeg == 1 ) { + // costruisco la curva di Bezier e la inserisco nella curva composita + PtrOwner pCrvBez( CreateCurveBezier()) ; + if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat)) + return nullptr ; + if ( ! cnData.bRat) { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + if ( ! pCrvBez->SetControlPoint( i, vBC[i])) + return nullptr ; + } + } + else { + for ( int i = 0 ; i <= cnData.nDeg ; ++ i) { + if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i])) + return nullptr ; + } + } + if ( ! pCrvBez->IsAPoint()) { + if ( ! pCrvCompo->AddCurve( Release( pCrvBez))) + return nullptr ; + } + } + // restituisco la curva composita return Release( pCrvCompo) ; }