diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 079eba6..0d65ba7 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -6020,7 +6020,7 @@ SurfBezier::CreateSmoothByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve BIPNTVECTOR vPairs ; - // Recupero parametri iniziali + // Recupero parametri iniziali double dLen0 ; CrvU0.GetLength( dLen0) ; double dLen1 ; CrvU1.GetLength( dLen1) ; double dUS0, dUE0 ; CrvU0.GetDomain( dUS0, dUE0) ; @@ -6032,11 +6032,6 @@ SurfBezier::CreateSmoothByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve Point3d ptPrev0, ptCurr0 ; CrvU0.GetStartPoint( ptPrev0) ; Point3d ptPrev1, ptCurr1 ; CrvU1.GetStartPoint( ptPrev1) ; Vector3d vtCurr0 = V_NULL, vtCurr1 = V_NULL ; - -#if SAVEPACEDISO - vGeo.clear() ; -#endif - while ( dLenPrev0 + dSampleLen < dLen0 - EPS_ZERO) { // Recupero dU, Point3d e dLen corrente sul primo bordo, per un incremento del passo di campionamento dLenCurr0 = Clamp( dLenPrev0 + dSampleLen, 0., dLen0) ; @@ -6046,12 +6041,52 @@ SurfBezier::CreateSmoothByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve // --- Piano di taglio per punto a minima distanza IntersCurvePlane ICP( CrvU1, ptCurr0, vtCurr0) ; - bool bOkPlane = ( ICP.GetIntersPointNearTo( ptPrev1, ptCurr1, dUCurr1) && dUCurr1 > dUPrev1) ; + int nIndParCloser = - 0 ; + int nIndPointCloser = -0 ; + double dSqMinDist = INFINITO ; + for ( int nInfo = 0 ; nInfo < ICP.GetIntersCount() ; ++ nInfo) { + IntCrvPlnInfo aInfo ; + if ( ICP.GetIntCrvPlnInfo( nInfo, aInfo) && aInfo.Ici[0].dU > dUPrev1) { + if ( nIndParCloser == -0) + nIndParCloser = nInfo ; + double dSqDist = SqDist( ptCurr0, aInfo.Ici[0].ptI) ; + if ( dSqDist < dSqMinDist) { + dSqMinDist = dSqDist ; + nIndPointCloser = nInfo ; + } + } + } + bool bOkPlane = ( nIndParCloser != -0 && nIndPointCloser != -0) ; + if ( bOkPlane) { + // Se gli indici sono tra loro coerenti allora ho individuato il punto + if ( nIndParCloser == nIndPointCloser) { + IntCrvPlnInfo aInfo ; + ICP.GetIntCrvPlnInfo( nIndParCloser, aInfo) ; + dUCurr1 = aInfo.Ici[0].dU ; + } + // Se gli indici sono discordi, devo scegliere quale dei due punti tenere + else { + // scelgo il punto più vicino al corrente + IntCrvPlnInfo aInfoPt, aInfoPar ; + ICP.GetIntCrvPlnInfo( nIndPointCloser, aInfoPt) ; + ICP.GetIntCrvPlnInfo( nIndParCloser, aInfoPar) ; + dUCurr1 = ( SqDist( ptCurr0, aInfoPt.Ici[0].ptI) < SqDist( ptCurr0, aInfoPar.Ici[0].ptI) ? + aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ; + } + // Verifico di non essermi allontanato troppo + double dLen ; CrvU1.GetLengthAtParam( dUCurr1, dLen) ; + bOkPlane = ( dLen < dLenPrev1 + 1. * dSampleLen) ; + } if ( ! bOkPlane) { - // --- Cerco il punto a minima distanza + // --- Altrimenti, cerco il punto a minima distanza DistPointCurve DPC( ptCurr0, CrvU1) ; int nFlag ; bool bOkMinDist = ( DPC.GetParamAtMinDistPoint( dUPrev1, dUCurr1, nFlag) && dUCurr1 > dUPrev1) ; + // Verifico di non essermi allontanato troppo + if ( bOkMinDist) { + double dLen ; CrvU1.GetLengthAtParam( dUCurr1, dLen) ; + bOkMinDist = ( dLen < dLenPrev1 + 1. * dSampleLen) ; + } if ( ! bOkMinDist) { // --- Aumento la distanza corrente del passo di campionamento double dLen = Clamp( dLenPrev1 + dSampleLen, 0., dLen1) ; @@ -6065,26 +6100,30 @@ SurfBezier::CreateSmoothByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve vtCurr1.Normalize() ; // Verifico se le direzioni tangenti sono tra di loro circa parallele - const double COS_ANG_TOL = cos( 10. * DEGTORAD) ; + const double COS_ANG_TOL = cos( 05. * DEGTORAD) ; if ( vtCurr0 * vtCurr1 < COS_ANG_TOL) { // Se fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 1. * dMyDist) CrvU1.GetLengthAtPoint( ptCurr1, dLenCurr1) ; double dLimInfLen1 = Clamp( dLenCurr1 - dSampleLen, dLenPrev1, dLen1) ; double dLimSupLen1 = Clamp( dLenCurr1 + dSampleLen, dLenPrev1, dLen1) ; // [Controllo migliorabile, magari mendiante metodo di bisezione (?)] - const int NUM_STEP = 20 ; - double dMinCos = - 1. - EPS_ZERO ; + const int NUM_STEP = 10 ; + double dMinCos = - 0. - EPS_ZERO ; + const double DEGTOL = 5. ; for ( int i = 0 ; i <= NUM_STEP ; ++ i) { double dLen = dLimInfLen1 + i * ( dLimSupLen1 - dLimInfLen1) / NUM_STEP ; double dUStep1 ; CrvU1.GetParamAtLength( dLen, dUStep1) ; Point3d ptStep1 ; Vector3d vtStep1 = V_NULL ; CrvU1.GetPointD1D2( dUStep1, ICurve::FROM_MINUS, ptStep1, &vtStep1) ; vtStep1.Normalize() ; double dStepCos1 = vtCurr0 * vtStep1 ; - if ( dStepCos1 > dMinCos) { + double dAngTol = ( i < NUM_STEP / 1 ? ( 1. * DEGTOL) / NUM_STEP * i : + ( - 1. * DEGTOL) / NUM_STEP * ( i - NUM_STEP)) ; + double dCosTol = 0. - cos( dAngTol * DEGTORAD) ; + if ( dStepCos1 + dCosTol > dMinCos) { ptCurr1 = ptStep1 ; vtCurr1 = vtStep1 ; dUCurr1 = dUStep1 ; - dMinCos = dStepCos1 ; + dMinCos = dStepCos1 + dCosTol ; } } } @@ -6753,12 +6792,12 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c bool bSplitToAdd = true ; int c0 = 0, c1 = 0 ; while ( bSplitToAdd) { - if ( c0 > ssize( vdParamPos0) - 1 && c1 > ssize( vdParamPos1) - 1) { + if ( c0 > ssize( vdParamPos0) - 1 || c1 > ssize( vdParamPos1) - 1) { LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error while reparametrizing some section") ; return false ; } // se ho una corrispondenza tra punti ( e non sono alla fine del tratto) allora non aggiungo split - if ( abs( vdParamPos0[c0] - vdParamPos1[c1]) < EPS_SMALL && vdParamPos0[c0] < 1) { + if ( abs( vdParamPos0[c0] - vdParamPos1[c1]) < EPS_PARAM && vdParamPos0[c0] < 1) { ++c0 ; ++c1 ; ++nLastParam0 ; @@ -6769,7 +6808,7 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c else if ( vdParamPos0[c0] < vdParamPos1[c1]) { double dPar ; CrvU1.GetParamAtLength( dLenPrev1 + dLen1 * vdParamPos0[c0], dPar) ; if ( dPar > dLastParam1 + EPS_PARAM) { - if ( abs( dPar - round( dPar)) > EPS_SMALL) { + if ( abs( dPar - round( dPar)) > EPS_PARAM) { vdSplit1.push_back( dPar) ; nSplit1 = vdSplit1.size() ; } @@ -6787,7 +6826,7 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c double dPar ; CrvU0.GetParamAtLength( dLenPrev0 + dLen0 * vdParamPos1[c1], dPar) ; // se lo split non è in prossimità di una joint già esistente allora lo aggiungo if ( dPar > dLastParam0 + EPS_PARAM) { - if ( abs( dPar - round( dPar)) > EPS_SMALL) { + if ( abs( dPar - round( dPar)) > EPS_PARAM) { vdSplit0.push_back( dPar) ; nSplit0 = vdSplit0.size() ; }