diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 301b1fc..d145113 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -3943,7 +3943,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int } else { // qui devo capire se aggiungere la nuova sottocurva prima o dopo la ripetizione dei punti - // se il match del punto della seconda curva è uguale al punto a cui ero arrivato sulla prima curva allora prima aggiungo la ripetizione di punti + // se il match del punto della U1 è uguale al punto a cui ero arrivato sulla U0 allora prima aggiungo la ripetizione di punti // se invece il match è più avanti allora aggiuno prima la curva e poi la ripetzione di punti bool bSubCurveAddedFirst = false ; if ( vPnt1Match[vPnt0Match[i+1].second].second != i+1 ) { @@ -4192,7 +4192,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int ++c ; continue ; } - else if ( dParam > nSpanU1 + EPS_SMALL ) { + else if ( dParam > nSpanU1 - EPS_SMALL ) { vbRep0[c] = nAtEnd1 == 0 ? false : true ; vbRep0.back() = true ; ++ nAtEnd1 ; @@ -4210,8 +4210,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int dLastParamMatch = dParam ; ptLastPointMatch = ptJoint ; nCrvCount = pCrvU1->GetCurveCount() ; - //pCrvU1->AddJoint( dParam) ; - // se sono già troppo vicino ad un split esistente allora non faccio nulla if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { ++c ; @@ -4223,24 +4221,33 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int int nCase = 0 ; for ( int j = 0 ; j < int( vMatch1.size()) ; ++j) { if ( abs(vMatch1[j].second - (c + 1)) < EPS_SMALL) { - ++nRep1 ; - // capisco se il punto è rep o se lo è il suo successivo - if( j + 1 < dParam) - nCase = 1 ; - else - nCase = 2 ; + // devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione + bool bFoundMatch = false ; + for ( int z = int( vMatch1[j].second) ; z < int( vdMatch0.size()) ; ++z) { + if ( abs( vdMatch0[z] - ( j + 1 )) < EPS_SMALL ) { + bFoundMatch = true ; + break ; + } + } + + if ( ! bFoundMatch) { + ++nRep1 ; + // capisco se il punto è rep o se lo è il suo successivo + if( j + 1 < dParam) + nCase = 1 ; + else + nCase = 2 ; + } break ; } } vnAddedOrNextIsRep0.push_back( nCase) ; } - - //nSpanU1 = pCrvU1->GetCurveCount() ; ++c ; } int nAtStart0 = 0 ; int nAtEnd0 = 0 ; - /*Point3d ptP1 ;*/ plU1.GetFirstPoint( ptP1) ; + plU1.GetFirstPoint( ptP1) ; c = 0 ; dLastParamMatch = 0 ; ptLastPointMatch = ptP1 ; @@ -4248,7 +4255,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int DBLVECTOR vdSplit1 ; BOOLVECTOR vbRep1( plU1.GetPointNbr() - 1) ; fill( vbRep1.begin(), vbRep1.end(), false) ; - bool bPrevWasRep = false ; while ( plU1.GetNextPoint( ptP1, true)) { DistPointCurve dpc( ptP1, *pCrvU0, false) ; int nFlag = 0 ; @@ -4278,11 +4284,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int dLastParamMatch = dParam ; ptLastPointMatch = ptJoint ; nCrvCount = pCrvU0->GetCurveCount() ; - //pCrvU0->AddJoint( dParam) ; - //// se ho aggiunto un nuovo punto alla curva U0 allora devo allungare coerentemente il vettore vbRep0 - //if( nCrvCount != pCrvU0->GetCurveCount()) - // vbRep0.insert( vbRep0.begin() + int(round( dParam - 0.5)), false) ; - //se sono troppo vicino ad uno split esistente allora non faccio nulla if( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { ++c ; @@ -4290,45 +4291,39 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int } vdSplit1.push_back( dParam) ; // verifico se ho un match per questo punto - // in tal caso vuol dire che sto creando una ripetizione nRep1 + // in tal caso vuol dire che sto creando una ripetizione nRep0 int nCase = 0 ; for ( int j = 0 ; j < int( vdMatch0.size()) ; ++j) { if ( abs(vdMatch0[j] - (c + 1)) < EPS_SMALL) { - ++nRep0 ; - // capisco se il punto è rep o se lo è il suo successivo - if( j + 1 < dParam) - nCase = 1 ; - else - nCase = 2 ; + // devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione + bool bFoundMatch = false ; + for ( int z = int( vdMatch0[j]) ; z < int( vMatch1.size()) ; ++z) { + if ( abs( vMatch1[z].second - ( j + 1 )) < EPS_SMALL ) { + bFoundMatch = true ; + break ; + } + } + + if ( ! bFoundMatch) { + ++nRep0 ; + // capisco se il punto è rep o se lo è il suo successivo + if( j + 1 < dParam) + nCase = 1 ; + else + nCase = 2 ; + } break ; } } vnAddedOrNextIsRep1.push_back( nCase) ; } - - //nSpanU0 = pCrvU0->GetCurveCount() ; ++c ; } - //// correggo il vettore vbRep1 aggiungendo gli elementi corrispondenti ai punti che ho aggiunto - //plU1.GetFirstPoint( ptP1) ; - //bool bAdvance = true ; - //for ( int i = 0 ; i < int( pCrvU1->GetCurveCount()) ; ++i) { - // if ( bAdvance) - // plU1.GetNextPoint( ptP1) ; - // const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( i)) ; - // Point3d ptSubEnd ; pSubCrv1->GetEndPoint( ptSubEnd) ; - // if ( ! AreSamePointApprox( ptP1, ptSubEnd)) { - // vbRep1.insert( vbRep1.begin() + i, false) ; - // bAdvance = false ; - // } - // else - // bAdvance = true ; - //} - - // applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep - int nUnit = int( vdSplit0.back()) ; + int nUnit = 0 ; + if ( ! vdSplit0.empty()) + nUnit = int( vdSplit0.back()) ; for ( int z = int( vdSplit0.size() - 1) ; z >= 0 ; --z) { double dSplit = vdSplit0[z] ; int nSplit = int( dSplit) ; @@ -4340,13 +4335,19 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int nUnit = nSplit ; pCrvU1->AddJoint( dSplit) ; switch( vnAddedOrNextIsRep0[z]) { - case 0 : vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ; + case 0 : if( vbRep1[nSplit]) + ++ nRep1 ; + vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo case 1 : vbRep1.insert( vbRep1.begin() + nSplit, true) ; break ; - case 2 : vbRep1[nSplit] = true ; + case 2 : if ( vbRep1[nSplit]) + --nRep1 ; + else + vbRep1[nSplit] = true ; vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ; } } - nUnit = int( vdSplit1.back()) ; + if( ! vdSplit1.empty()) + nUnit = int( vdSplit1.back()) ; for ( int z = int( vdSplit1.size() - 1) ; z >= 0 ; --z) { double dSplit = vdSplit1[z] ; int nSplit = int( dSplit) ; @@ -4358,16 +4359,47 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int nUnit = nSplit ; pCrvU0->AddJoint( dSplit) ; switch( vnAddedOrNextIsRep1[z]) { - case 0 : vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ; + case 0 : if( vbRep0[nSplit]) + ++ nRep0 ; + vbRep0.insert( vbRep0.begin() + nSplit, vbRep0[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo case 1 : vbRep0.insert( vbRep0.begin() + nSplit, true) ; break ; - case 2 : vbRep0[nSplit] = true ; - vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ; + case 2 : if( vbRep0[nSplit]) + -- nRep0 ; + else + vbRep0[nSplit] = true ; + vbRep0.insert( vbRep0.begin() + nSplit, false) ; break ; } } nSpanU0 = pCrvU0->GetCurveCount() ; nSpanU1 = pCrvU1->GetCurveCount() ; + //aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true + int nAddedSpan = 0 ; + int nCrv0 = 0 ; + int nCrv1 = 0 ; + while ( nAddedSpan < nSpanU0 + nAtStart0 + nAtEnd0 + nRep1) { + if ( nCrv0 >= nSpanU0) + nCrv0 = nSpanU0 - 1; + if ( nCrv1 >= nSpanU1) + nCrv1 = nSpanU1 - 1; + bool bRep0 = vbRep0[nCrv0] ; + bool bRep1 = vbRep1[nCrv1] ; + if ( bRep0 && bRep1 ) { + vbRep0[nCrv0] = false ; + bRep0 = false ; + vbRep1[nCrv1] = false ; + bRep1 = false ; + -- nRep0 ; + -- nRep1 ; + } + if ( ! bRep0) + ++ nCrv1 ; + if ( ! bRep1) + ++ nCrv0 ; + ++nAddedSpan ; + } + // trovo il numero di span che dovrà avere la superficie // ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0) nSpanU = nSpanU0 + nAtStart0 + nAtEnd0 + nRep1 ; @@ -4377,9 +4409,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ; // aggiungo i punti di controllo scorrendo in contemporanea le due curve - int nAddedSpan = 0 ; - int nCrv0 = 0 ; - int nCrv1 = 0 ; + nAddedSpan = 0 ; + nCrv0 = 0 ; + nCrv1 = 0 ; bool bLast0 = false ; bool bLast1 = false ; while ( nAddedSpan < nSpanU) { @@ -4392,24 +4424,25 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int bLast1 = true ; } bool bRep0 = vbRep0[nCrv0] ; + bool bRep1 = vbRep1[nCrv1] ; const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU0->GetCurve( nCrv0)) ; for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) { int nInd = i ; // se ho una ripetizione allora riaggiungo l'ultimo punto. Se sono ancora alla curva 0 invece devo aggiungere lo start della curva U0 - if ( vbRep1[nCrv1]) + if ( bRep1 || bLast0) nInd = ! bLast0 ? 0 : nDegU ; if ( ! bRat) SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd)) ; else SetControlPoint( nAddedSpan * nDegU + i, pSubCrv0->GetControlPoint( nInd), pSubCrv0->GetControlWeight( nInd)) ; } - if ( ! vbRep1[nCrv1]) + if ( ! bRep1) ++ nCrv0 ; const ICurveBezier* pSubCrv1 = GetCurveBezier( pCrvU1->GetCurve( nCrv1)) ; for( int i = nAddedSpan == 0 ? 0 : 1 ; i < nLastPoint ; ++ i) { int nInd = i ; // se ho una ripetizione allora riaggiungo l'ultimo punto. Se sono ancora alla curva 0 invece devo aggiungere lo start della curva U0 - if ( bRep0) + if ( bRep0 || bLast1) nInd = ! bLast1 ? 0 : nDegU ; if ( ! bRat) SetControlPoint( nSecondRowInd + nAddedSpan * nDegU + i, pSubCrv1->GetControlPoint( nInd)) ;