diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 64ddd2d..e9ae10c 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -4052,7 +4052,7 @@ GetPocketingOptimizedCurves( ISurfFlatRegion* pSfr, const PocketParams& PockPara //---------------------------------------------------------------------------- static bool -GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockParams, bool& bOutStart, +GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockParams, const Point3d& ptEndPrec, bool& bOutStart, Point3d& ptStart, Vector3d& vtOut) { // controllo dei parametri @@ -4070,22 +4070,34 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara pMyCrv = pCompo->GetNextCurve() ; } + // se ho un punto di riferimento, cambio il punto iniziale della curva, partendo da questa + PtrOwner pMyCompo( CloneCurveComposite( pCompo)) ; + if ( IsNull( pMyCompo) || ! pMyCompo->IsValid()) + return false ; + if ( ptEndPrec.IsValid()) { + double dMinDistPar = 0. ; + int nFlag = 0 ; + DistPointCurve( ptEndPrec, *pMyCompo).GetParamAtMinDistPoint( 0., dMinDistPar, nFlag) ; + if ( dMinDistPar > EPS_PARAM) + pMyCompo->ChangeStartPoint( floor( dMinDistPar)) ; + } + // richiedo lunghezza superiore a diametro utensile più doppio offset radiale double dRefLen = ( bAllOpen ? 0. : ( 2 * PockParams.dRad) + 2 * PockParams.dRadialOffset - EPS_SMALL) ; double dMaxLen = dRefLen ; // ciclo sulle singole curve - bool bFound = false ; - const ICurve* pPrevCrv = pCompo->GetLastCurve() ; + bool bFound = false, bFirst = true ; + const ICurve* pPrevCrv = pMyCompo->GetLastCurve() ; double dLenPrev = 0. ; if ( pPrevCrv != nullptr && pPrevCrv->GetTempProp() == TEMP_PROP_OPEN_EDGE) pPrevCrv->GetLength( dLenPrev) ; - const ICurve* pCrv = pCompo->GetFirstCurve() ; + const ICurve* pCrv = pMyCompo->GetFirstCurve() ; while ( pCrv != nullptr) { // analizzo la curva successiva - const ICurve* pNextCrv = pCompo->GetNextCurve() ; + const ICurve* pNextCrv = pMyCompo->GetNextCurve() ; bool bNextOk = ( pNextCrv != nullptr) ; if ( ! bNextOk) - pNextCrv = pCompo->GetFirstCurve() ; + pNextCrv = pMyCompo->GetFirstCurve() ; double dLenNext = 0. ; if ( pNextCrv != nullptr && pNextCrv->GetTempProp() == TEMP_PROP_OPEN_EDGE) pNextCrv->GetLength( dLenNext) ; @@ -4105,6 +4117,8 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara dLenAgg += max( 0.4, vtEnd * vtNextStart) * dLenNext ; } } + if ( ptEndPrec.IsValid() && bFirst) + dLenAgg += 2. * ( dLenPrev + dLenNext) ; // entità corrente double dLen = 0 ; if ( pCrv->GetLength( dLen)) { @@ -4118,6 +4132,7 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara ( abs( ptTest.z - ptStart.z) < 100 * EPS_SMALL && ptTest.y < ptStart.y - 100 * EPS_SMALL)) { dMaxLen = max( dMaxLen, dLen + dLenAgg) ; ptStart = ptTest ; + bOutStart = true ; // versore ortogonale verso l'esterno pCrv->GetMidDir( vtOut) ; vtOut.Rotate( Z_AX, 0, -1) ; @@ -4130,6 +4145,7 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara // versore ortogonale verso l'esterno vtOut.Normalize() ; vtOut.Rotate( Z_AX, 0, -1) ; + bOutStart = true ; bFound = true ; } } @@ -4141,6 +4157,7 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara // vado alla successiva pPrevCrv = pCrv ; pCrv = ( bNextOk ? pNextCrv : nullptr) ; + bFirst = false ; } return bFound ; @@ -4606,7 +4623,7 @@ SetPtStartForPath( ICurveComposite* pCrvOffs, const PocketParams& PockParams, co } // se punto non trovato precedentemente, tento con una sottocurva OPEN generica if ( ! bMidOut) { - if ( ! GetParamOnOpenCurve( pCrvOffs, PockParams, bMidOut, ptStart, vtMidOut)) + if ( ! GetParamOnOpenCurve( pCrvOffs, PockParams, ptEndPrec, bMidOut, ptStart, vtMidOut)) return false ; } // se queste curve sono troppo corte, analizzo le parti uniformi diff --git a/CurveAux.cpp b/CurveAux.cpp index 5299277..e330f0a 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -25,19 +25,24 @@ #include "IntersLineLine.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkStringUtils3d.h" -#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkUiUnits.h" -#include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkIntersCurvePlane.h" #include "/EgtDev/Include/EGkCurveByInterp.h" #include "/EgtDev/Include/EGkChainCurves.h" +#include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EgtPointerOwner.h" #define EIGEN_NO_IO #include "/EgtDev/Extern/Eigen/Dense" #define SAVEAPPROX 0 #define SAVECURVEPASSED 0 #define SAVELINEARAPPROX 0 -#if SAVEAPPROX || SAVECURVEPASSED || SAVELINEARAPPROX +#define SAVESYNCLINES 0 +#if SAVEAPPROX || SAVECURVEPASSED || SAVELINEARAPPROX || SAVESYNCLINES +#include "/EgtDev/Include/EGkGeoPoint3d.h" static int nCrvPassed = 0 ; + std::vector VT ; + std::vector VC ; #include "/EgtDev/Include/EGkGeoObjSave.h" #endif @@ -2697,3 +2702,115 @@ GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) } return true ; } + +//---------------------------------------------------------------------------- +bool +GetIsoPointOnSecondCurve( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, double dUCurr1, double& dUCurr2, double dMyDist, double dUPrev2, + double dLenPrev2, double& dLenCurr2, double dLen2) +{ + Point3d ptCurr1 ; + Vector3d vtCurr1 ; + pCrvEdge1->GetPointD1D2( dUCurr1, ICurve::FROM_MINUS, ptCurr1, &vtCurr1) ; + // --- Piano di taglio per punto a minima distanza + IntersCurvePlane ICP( *pCrvEdge2, ptCurr1, vtCurr1) ; + int nIndParCloser = - 1, nIndPointCloser = -1 ; + double dSqMinDist = INFINITO ; + for ( int nInfo = 0 ; nInfo < ICP.GetIntersCount() ; ++ nInfo) { + IntCrvPlnInfo aInfo ; + if ( ICP.GetIntCrvPlnInfo( nInfo, aInfo) && aInfo.Ici[0].dU > dUPrev2) { + if ( nIndParCloser == -1) + nIndParCloser = nInfo ; + double dSqDist = SqDist( ptCurr1, aInfo.Ici[0].ptI) ; + if ( dSqDist < dSqMinDist) { + dSqMinDist = dSqDist ; + nIndPointCloser = nInfo ; + } + } + } + bool bOkPlane = ( nIndParCloser != -1 && nIndPointCloser != -1) ; + if ( bOkPlane) { + // Se gli indici sono tra loro coerenti allora ho individuato il punto + if ( nIndParCloser == nIndPointCloser) { + IntCrvPlnInfo aInfo ; + ICP.GetIntCrvPlnInfo( nIndParCloser, aInfo) ; + dUCurr2 = 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) ; + dUCurr2 = ( SqDist( ptCurr1, aInfoPt.Ici[0].ptI) < SqDist( ptCurr1, aInfoPar.Ici[0].ptI) ? + aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ; +#if SAVESYNCLINES + VT.clear() ; VC.clear() ; + VT.emplace_back( pCrvEdge1->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ; + VT.emplace_back( pCrvEdge2->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ; + PtrOwner ptCurr1Geo( CreateGeoPoint3d()) ; ptCurr1Geo->Set( ptCurr1) ; + VT.emplace_back( Release( ptCurr1Geo)) ; VC.emplace_back( BLUE) ; + PtrOwner ptPar( CreateGeoPoint3d()) ; ptPar->Set( aInfoPar.Ici[0].ptI) ; + PtrOwner ptPt( CreateGeoPoint3d()) ; ptPt->Set( aInfoPt.Ici[0].ptI) ; + VT.emplace_back( Release( ptPar)) ; VC.emplace_back( LIME) ; + VT.emplace_back( Release( ptPt)) ; VC.emplace_back( FUCHSIA) ; + SaveGeoObj( VT, VC, "C:\\Temp\\bezier\\ruled\\TestTrimmingPlane.nge") ; +#endif + } + // Verifico di non essermi allontanato troppo + double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ; + bOkPlane = ( dLen < dLenPrev2 + 2. * dMyDist) ; + } + if ( ! bOkPlane) { + // --- Altrimenti, cerco il punto a minima distanza + DistPointCurve DPC( ptCurr1, *pCrvEdge2) ; + int nFlag ; + bool bOkMinDist = ( DPC.GetParamAtMinDistPoint( dUPrev2, dUCurr2, nFlag) && dUCurr2 > dUPrev2) ; + // Verifico di non essermi allontanato troppo + if ( bOkMinDist) { + double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ; + bOkMinDist = ( dLen < dLenPrev2 + 2. * dMyDist) ; + } + if ( ! bOkMinDist) { + // --- Aumento la distanza corrente del passo di campionamento + double dLen = Clamp( dLenPrev2 + dMyDist, 0., dLen2) ; + pCrvEdge2->GetParamAtLength( dLen, dUCurr2) ; + } + } + + // Recupero il punto corrente e la direzione tangente sul secondo bordo + pCrvEdge2->GetLengthAtParam( dUCurr2, dLenCurr2) ; + Point3d ptCurr2 ; + Vector3d vtCurr2 ; + pCrvEdge2->GetPointD1D2( dUCurr2, ICurve::FROM_MINUS, ptCurr2, &vtCurr2) ; + vtCurr2.Normalize() ; + + // Verifico se le direzioni tangenti sono tra di loro circa parallele + const double COS_ANG_TOL = cos( 15. * DEGTORAD) ; + if ( vtCurr1 * vtCurr2 < COS_ANG_TOL) { + // Se fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 2. * dMyDist) + pCrvEdge2->GetLengthAtPoint( ptCurr2, dLenCurr2) ; + double dLimInfLen2 = Clamp( dLenCurr2 - dMyDist, dLenPrev2, dLen2) ; + double dLimSupLen2 = Clamp( dLenCurr2 + dMyDist, dLenPrev2, dLen2) ; + // [Controllo migliorabile, magari mendiante metodo di bisezione (?)] + const int NUM_STEP = 20 ; + double dMinCos = - 1. - EPS_ZERO ; + const double DEGTOL = 5. ; + for ( int i = 0 ; i <= NUM_STEP ; ++ i) { + double dLen = dLimInfLen2 + i * ( dLimSupLen2 - dLimInfLen2) / NUM_STEP ; + double dUStep2 ; pCrvEdge2->GetParamAtLength( dLen, dUStep2) ; + Point3d ptStep2 ; Vector3d vtStep2 = V_NULL ; + pCrvEdge2->GetPointD1D2( dUStep2, ICurve::FROM_MINUS, ptStep2, &vtStep2) ; vtStep2.Normalize() ; + double dStepCos2 = vtCurr1 * vtStep2 ; + double dAngTol = ( i < NUM_STEP / 2 ? ( 2. * DEGTOL) / NUM_STEP * i : + ( - 2. * DEGTOL) / NUM_STEP * ( i - NUM_STEP)) ; + double dCosTol = 1. - cos( dAngTol * DEGTORAD) ; + if ( dStepCos2 + dCosTol > dMinCos) { + ptCurr2 = ptStep2 ; + vtCurr2 = vtStep2 ; + dUCurr2 = dUStep2 ; + dMinCos = dStepCos2 + dCosTol ; + } + } + } + return true ; +} \ No newline at end of file diff --git a/CurveAux.h b/CurveAux.h index 58bfae4..56c1b8e 100644 --- a/CurveAux.h +++ b/CurveAux.h @@ -35,4 +35,4 @@ bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ; bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ; ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ; Voronoi* GetCurveVoronoi( const ICurve& crvC) ; -bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ; +bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ; \ No newline at end of file diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index d805427..9191679 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/SurfBezier.cpp b/SurfBezier.cpp index d2cfe86..fbb82b7 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -6402,7 +6402,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p #endif // Verifico che la distanza di campionamento sia ammissibile - double dSampleDist = Clamp( dSampleLen, 2., 30.) ; // 20.0 sembra un passo di campionamento ideale + double dMyDist = Clamp( dSampleLen, 2., 30.) ; // 20.0 sembra un passo di campionamento ideale // Recupero parametri iniziali double dLen1 ; pCrvEdge1->GetLength( dLen1) ; double dLen2 ; pCrvEdge2->GetLength( dLen2) ; @@ -6415,168 +6415,67 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p Point3d ptPrev1, ptCurr1 ; pCrvEdge1->GetStartPoint( ptPrev1) ; Point3d ptPrev2, ptCurr2 ; pCrvEdge2->GetStartPoint( ptPrev2) ; Vector3d vtCurr1 = V_NULL, vtCurr2 = V_NULL ; - while ( dLenPrev1 + dSampleDist < dLen1 - EPS_ZERO) { - // Recupero dU, Point3d e dLen corrente sul primo bordo, per un incremento del passo di campionamento - dLenCurr1 = Clamp( dLenPrev1 + dSampleDist, 0., dLen1) ; + + while ( dLenPrev1 + dMyDist < dLen1 - EPS_ZERO) { + // Recupero dU, Point3d e dLen corrente sul primo bordo, per un incremento del passo di campionamento + dLenCurr1 = Clamp( dLenPrev1 + dMyDist, 0., dLen1) ; pCrvEdge1->GetParamAtLength( dLenCurr1, dUCurr1) ; - // se sono abbastanza vicino ad una joint allora prendo quel punto - double dUClosestJoint1 = round( dUCurr1) ; - double dLenAlt1 = 0 ; pCrvEdge1->GetLengthAtParam( dUClosestJoint1, dLenAlt1) ; - if ( abs( dLenCurr1 - dLenAlt1) < 1) - dUCurr1 = dUClosestJoint1 ; + //// se sono abbastanza vicino ad una joint allora prendo quel punto + //double dUClosestJoint1 = round( dUCurr1) ; + //double dLenAlt1 = 0 ; pCrvEdge1->GetLengthAtParam( dUClosestJoint1, dLenAlt1) ; + //if ( abs( dLenCurr1 - dLenAlt1) < 1) + // dUCurr1 = dUClosestJoint1 ; pCrvEdge1->GetPointD1D2( dUCurr1, ICurve::FROM_MINUS, ptCurr1, &vtCurr1) ; vtCurr1.Normalize() ; - #if DEBUG_SYNCLINES - PtrOwner ptGeo1( CreateGeoPoint3d()) ; ptGeo1->Set( ptCurr1) ; - PtrOwner vtGeo1( CreateGeoVector3d()) ; vtGeo1->Set( 5. * vtCurr1, ptCurr1) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( ptGeo1)) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( vtGeo1)) ; - #endif +#if DEBUG_SYNCLINES + PtrOwner ptGeo1( CreateGeoPoint3d()) ; ptGeo1->Set( ptCurr1) ; + PtrOwner vtGeo1( CreateGeoVector3d()) ; vtGeo1->Set( 5. * vtCurr1, ptCurr1) ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( ptGeo1)) ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( vtGeo1)) ; +#endif - // --- Piano di taglio per punto a minima distanza - IntersCurvePlane ICP( *pCrvEdge2, ptCurr1, vtCurr1) ; - int nIndParCloser = - 1, nIndPointCloser = -1 ; - double dSqMinDist = INFINITO ; - for ( int nInfo = 0 ; nInfo < ICP.GetIntersCount() ; ++ nInfo) { - IntCrvPlnInfo aInfo ; - if ( ICP.GetIntCrvPlnInfo( nInfo, aInfo) && aInfo.Ici[0].dU > dUPrev2) { - if ( nIndParCloser == -1) - nIndParCloser = nInfo ; - double dSqDist = SqDist( ptCurr1, aInfo.Ici[0].ptI) ; - if ( dSqDist < dSqMinDist) { - dSqMinDist = dSqDist ; - nIndPointCloser = nInfo ; - } - } - } - bool bOkPlane = ( nIndParCloser != -1 && nIndPointCloser != -1) ; - if ( bOkPlane) { - // Se gli indici sono tra loro coerenti allora ho individuato il punto - if ( nIndParCloser == nIndPointCloser) { - IntCrvPlnInfo aInfo ; - ICP.GetIntCrvPlnInfo( nIndParCloser, aInfo) ; - dUCurr2 = 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) ; - dUCurr2 = ( SqDist( ptCurr1, aInfoPt.Ici[0].ptI) < SqDist( ptCurr1, aInfoPar.Ici[0].ptI) ? - aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ; - #if DEBUG_SYNCLINES && 0 - VT.clear() ; VC.clear() ; - VT.emplace_back( pCrvEdge1->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ; - VT.emplace_back( pCrvEdge2->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ; - PtrOwner ptCurr1Geo( CreateGeoPoint3d()) ; ptCurr1Geo->Set( ptCurr1) ; - VT.emplace_back( Release( ptCurr1Geo)) ; VC.emplace_back( BLUE) ; - PtrOwner ptPar( CreateGeoPoint3d()) ; ptPar->Set( aInfoPar.Ici[0].ptI) ; - PtrOwner ptPt( CreateGeoPoint3d()) ; ptPt->Set( aInfoPt.Ici[0].ptI) ; - VT.emplace_back( Release( ptPar)) ; VC.emplace_back( LIME) ; - VT.emplace_back( Release( ptPt)) ; VC.emplace_back( FUCHSIA) ; - SaveGeoObj( VT, VC, "C:\\Temp\\TestTrimmingPlane.nge") ; - #endif - } - // Verifico di non essermi allontanato troppo - double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ; - bOkPlane = ( dLen < dLenPrev2 + 2. * dSampleDist) ; - } - if ( ! bOkPlane) { - // --- Altrimenti, cerco il punto a minima distanza - DistPointCurve DPC( ptCurr1, *pCrvEdge2) ; - int nFlag ; - bool bOkMinDist = ( DPC.GetParamAtMinDistPoint( dUPrev2, dUCurr2, nFlag) && dUCurr2 > dUPrev2) ; - // Verifico di non essermi allontanato troppo - if ( bOkMinDist) { - double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ; - bOkMinDist = ( dLen < dLenPrev2 + 2. * dSampleDist) ; - } - if ( ! bOkMinDist) { - // --- Aumento la distanza corrente del passo di campionamento - double dLen = Clamp( dLenPrev2 + dSampleDist, 0., dLen2) ; - pCrvEdge2->GetParamAtLength( dLen, dUCurr2) ; - } - } + GetIsoPointOnSecondCurve( pCrvEdge1, pCrvEdge2, dUCurr1, dUCurr2, dMyDist, dUPrev2, dLenPrev2, dLenCurr2, dLen2) ; - // Recupero il punto corrente e la direzione tangente sul secondo bordo - pCrvEdge2->GetLengthAtParam( dUCurr2, dLenCurr2) ; + //// verifico se sono vicino ad una joint esistente allora modifico la curva 2 + //double dUClosestJoint2 = round( dUCurr2) ; + //double dLenAlt2 = 0 ; pCrvEdge2->GetLengthAtParam( dUClosestJoint2, dLenAlt2) ; + //if ( abs( dLenCurr1 - dLenAlt2) < 1) { + // Point3d ptNewJoint ; pCrvEdge2->GetPointD1D2( dUClosestJoint2, ICurve::FROM_MINUS, ptNewJoint) ; + // pCrvEdge2->ModifyJoint( int( dUClosestJoint2), ptNewJoint) ; + // dUCurr2 = dUClosestJoint2 ; + //} pCrvEdge2->GetPointD1D2( dUCurr2, ICurve::FROM_MINUS, ptCurr2, &vtCurr2) ; - vtCurr2.Normalize() ; - // Verifico se le direzioni tangenti sono tra di loro circa parallele - const double COS_ANG_TOL = cos( 15. * DEGTORAD) ; - if ( vtCurr1 * vtCurr2 < COS_ANG_TOL) { - // Se fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 2. * dMyDist) - pCrvEdge2->GetLengthAtPoint( ptCurr2, dLenCurr2) ; - double dLimInfLen2 = Clamp( dLenCurr2 - dSampleDist, dLenPrev2, dLen2) ; - double dLimSupLen2 = Clamp( dLenCurr2 + dSampleDist, dLenPrev2, dLen2) ; - // [Controllo migliorabile, magari mendiante metodo di bisezione (?)] - const int NUM_STEP = 20 ; - double dMinCos = - 1. - EPS_ZERO ; - const double DEGTOL = 5. ; - for ( int i = 0 ; i <= NUM_STEP ; ++ i) { - double dLen = dLimInfLen2 + i * ( dLimSupLen2 - dLimInfLen2) / NUM_STEP ; - double dUStep2 ; pCrvEdge2->GetParamAtLength( dLen, dUStep2) ; - Point3d ptStep2 ; Vector3d vtStep2 = V_NULL ; - pCrvEdge2->GetPointD1D2( dUStep2, ICurve::FROM_MINUS, ptStep2, &vtStep2) ; vtStep2.Normalize() ; - double dStepCos2 = vtCurr1 * vtStep2 ; - double dAngTol = ( i < NUM_STEP / 2 ? ( 2. * DEGTOL) / NUM_STEP * i : - ( - 2. * DEGTOL) / NUM_STEP * ( i - NUM_STEP)) ; - double dCosTol = 1. - cos( dAngTol * DEGTORAD) ; - if ( dStepCos2 + dCosTol > dMinCos) { - ptCurr2 = ptStep2 ; - vtCurr2 = vtStep2 ; - dUCurr2 = dUStep2 ; - dMinCos = dStepCos2 + dCosTol ; - } - } - } - - // verifico se sono vicino ad una joint esistente allora modifico la curva 2 - double dUClosestJoint2 = round( dUCurr2) ; - double dLenAlt2 = 0 ; pCrvEdge2->GetLengthAtParam( dUClosestJoint2, dLenAlt2) ; - if ( abs( dLenCurr1 - dLenAlt2) < 1) { - Point3d ptNewJoint ; pCrvEdge2->GetPointD1D2( dUClosestJoint2, ICurve::FROM_MINUS, ptNewJoint) ; - pCrvEdge2->ModifyJoint( int( dUClosestJoint2), ptNewJoint) ; - dUCurr2 = dUClosestJoint2 ; - } - - #if DEBUG_SYNCLINES - PtrOwner ptGeo2( CreateGeoPoint3d()) ; ptGeo2->Set( ptCurr2) ; - PtrOwner vtGeo2( CreateGeoVector3d()) ; vtGeo2->Set( 5. * vtCurr2, ptCurr2) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( ptGeo2)) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( vtGeo2)) ; - #endif - -#if SAVEPACEDISO - // Inserisco le curve di sincronizzazione nel Layer di destinazine - PtrOwner pLine( CreateCurveLine()) ; pLine->Set( ptCurr1, ptCurr2) ; - vGeo.push_back( Release( pLine)) ; - vCol.push_back( LIME) ; +#if DEBUG_SYNCLINES + PtrOwner ptGeo2( CreateGeoPoint3d()) ; ptGeo2->Set( ptCurr2) ; + PtrOwner vtGeo2( CreateGeoVector3d()) ; vtGeo2->Set( 5. * vtCurr2, ptCurr2) ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( ptGeo2)) ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( vtGeo2)) ; #endif vSyncLines.emplace_back( ptCurr1, ptCurr2) ; - // --- Analisi degli spigoli all'interno della Quadrangolazione corrente --- - // NB. Non è sempre detto che uno spigolo di una curva sia sincronizzato con lo spigolo di un'altra ( se questi esistono)... - // Pertanto la Bezier Ruled ricavata non è detto che sia in grado di approssimare lo spigolo correttamente, potrebbe sdondarlo + //// Inserisco le curve di sincronizzazione nel Layer di destinazine + //PtrOwner pLine( CreateCurveLine()) ; pLine->Set( ptCurr1, ptCurr2) ; + //pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrp, Release( pLine)) ; + + // --- Analisi degli spigoli all'interno della Quadrangolazione corrente --- + // NB. Non è sempre detto che uno spigolo di una curva sia sincronizzato con lo spigolo di un'altra ( se questi esistono)... + // Pertanto la Bezier Ruled ricavata non è detto che sia in grado di approssimare lo spigolo correttamente, potrebbe sdondarlo PtrOwner pCrvQuad1( ConvertCurveToComposite( pCrvEdge1->CopyParamRange( dUPrev1, dUCurr1))) ; PtrOwner pCrvQuad2( ConvertCurveToComposite( pCrvEdge2->CopyParamRange( dUPrev2, dUCurr2))) ; BIPNTVECTOR vEdgeSyncLines ; ManageEdgesInQuadrangulation( pCrvQuad1, pCrvQuad2, vEdgeSyncLines) ; -#if SAVEPACEDISO - for ( int i = 0 ; i < ssize( vEdgeSyncLines) ; ++ i) { - PtrOwner pLine( CreateCurveLine()) ; pLine->Set( vEdgeSyncLines[i].first, vEdgeSyncLines[i].second) ; - vGeo.push_back( Release( pLine)) ; - vCol.push_back( GREEN) ; - } -#endif + //for ( int i = 0 ; i < ssize( vEdgeSyncLines) ; ++ i) { + // PtrOwner pLine( CreateCurveLine()) ; pLine->Set( vEdgeSyncLines[i].first, vEdgeSyncLines[i].second) ; + // int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrp, Release( pLine)) ; + // pGeomDB->SetMaterial( nNewId, GREEN) ; + //} - // --- Aggiunta di Linee di Sync all'interno della Quandrangolazione corrente --- - // Perchè parametrizzando per la lunghezza i SottoTratti ricavati, nel caso di elevate variazioni angolari tra l'inizio e la fine - // ( tra due curva di Sync) si potrebbero generare delle torsioni non volute - // -->! NB. Queste linee vengono create considerando le SubQuadrangolazioni con gli Spigoli. !<-- + // --- Aggiunta di Linee di Sync all'interno della Quandrangolazione corrente --- + // Perchè parametrizzando per la lunghezza i SottoTratti ricavati, nel caso di elevate variazioni angolari tra l'inizio e la fine + // ( tra due curva di Sync) si potrebbero generare delle torsioni non volute + // -->! NB. Queste linee vengono create considerando le SubQuadrangolazioni con gli Spigoli. !<-- BIPNTVECTOR vTwistSyncLines ; if ( vEdgeSyncLines.empty()) ManageTwistInQuadrangulation( pCrvQuad1, pCrvQuad2, vTwistSyncLines) ; @@ -6593,7 +6492,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p SyncLineNext.first = vEdgeSyncLines[i].first ; SyncLineNext.second = vEdgeSyncLines[i].second ; } - // Recupero i parametri correnti + // Recupero i parametri correnti double dUS1, dUE1, dUS2, dUE2 ; pCrvQuad1->GetParamAtPoint( SyncLinePrev.first, dUS1) ; pCrvQuad2->GetParamAtPoint( SyncLinePrev.second, dUS2) ; @@ -6602,22 +6501,15 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p PtrOwner pCrvSubQuad1( ConvertCurveToComposite( pCrvQuad1->CopyParamRange( dUS1, dUE1))) ; PtrOwner pCrvSubQuad2( ConvertCurveToComposite( pCrvQuad2->CopyParamRange( dUE1, dUE2))) ; ManageTwistInQuadrangulation( pCrvSubQuad1, pCrvSubQuad2, vTwistSyncLines) ; - // Aggiorno i parametri + // Aggiorno i parametri SyncLinePrev = SyncLineNext ; } } // aggiungo le nuove curve ( non importa che siano in ordine di parametro) vSyncLines.insert( vSyncLines.end(), vEdgeSyncLines.begin(), vEdgeSyncLines.end()) ; vSyncLines.insert( vSyncLines.end(), vTwistSyncLines.begin(), vTwistSyncLines.end()) ; -#if SAVEPACEDISO - for ( int i = 0 ; i < ssize( vTwistSyncLines) ; ++ i) { - PtrOwner pLine( CreateCurveLine()) ; pLine->Set( vTwistSyncLines[i].first, vTwistSyncLines[i].second) ; - vGeo.push_back( Release( pLine)) ; - vCol.push_back( OLIVE) ; - } -#endif - // Aggiorno i parametri + // Aggiorno i parametri ptPrev1 = ptCurr1 ; dUPrev1 = dUCurr1 ; dLenPrev1 = dLenCurr1 ; ptPrev2 = ptCurr2 ; dUPrev2 = dUCurr2 ; dLenPrev2 = dLenCurr2 ; } diff --git a/Trimming.cpp b/Trimming.cpp index 985984a..699f2e0 100644 --- a/Trimming.cpp +++ b/Trimming.cpp @@ -63,7 +63,7 @@ #define DEBUG_EDGES 0 #define DEBUG_SHAPE_STM 0 #define DEBUG_HOLES 0 -#define DEBUG_SMOOTH_CURVATURE 1 +#define DEBUG_SMOOTH_CURVATURE 0 #if DEBUG_BASIC_BORDERS || DEBUG_CHAIN_CURVES || DEBUG_ANG_APPROX || DEBUG_BEZIER_INTERP || \ DEBUG_FACE_SEARCH || DEBUG_FACE_SEARCH_TRIA_MODIF || DEBUG_BRK_POINTS || DEBUG_BRK_THICK || \ DEBUG_BRK || DEBUG_BORDERS_BY_NORMALS || DEBUG_SYNC_POINTS || DEBUG_SYNC_INTERPOLATION || \ @@ -3896,8 +3896,8 @@ GetTrimmingSurfBzSyncPoints( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, ! pCompoEdge1->IsValid() || ! pCompoEdge2->IsValid()) return false ; - // Controllo sulla tolleranza lineare - double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; + //// Controllo sulla tolleranza lineare + //double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; #if DEBUG_SYNC_POINTS VT.clear() ; VC.clear() ; @@ -3958,7 +3958,7 @@ GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, // Verifico i valori delle tolleranze double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; - double dMyAngTol = Clamp( dAngTol, EPS_ANG_SMALL, 60.) ; + //double dMyAngTol = Clamp( dAngTol, EPS_ANG_SMALL, 60.) ; // Verifico le due curve di sincronizzazione abbiano gli estremi sulle due curve di bordo Point3d ptS1 ; pSync1->GetStartPoint( ptS1) ; @@ -5019,10 +5019,6 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta Point3d ptS2 = bpIsoEnd.first ; Vector3d vtDir1 = bpIsoStart.second - ptS1 ; Vector3d vtDir2 = bpIsoEnd.second - ptS2 ; - double dInterpolateAngTol = 4 ; - double dAngInterp = 0 ; - vtDir1.GetAngle( vtDir2, dAngInterp) ; - bool bInterpolate = dAngInterp > dInterpolateAngTol ; int nDegU, nDegV, nSpanU, nSpanV ; bool bRat, bTrimmed ; @@ -5039,13 +5035,11 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta return nullptr ; int nUS1 = int ( dParS1) * nDegU ; int nUS2 = int ( dParS2) * nDegU ; - bool bInverted = false ; if ( nUS1 > nUS2) { swap( nUS1, nUS2) ; swap( dParS1, dParS2) ; swap( ptS1, ptS2) ; swap( vtDir1, vtDir2) ; - bInverted = true ; } PtrOwner pCrvOrig1( ConvertCurveToComposite( pCrv1->CopyParamRange( dParS1, dParS2))) ; PtrOwner pCrvOrig2( ConvertCurveToComposite( pCrv2->CopyParamRange( dParS1, dParS2))) ; @@ -5138,7 +5132,6 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta if ( pCC2->GetCurveCount() != nNewCrvs) return nullptr ; int nDiff = nNewCrvs - pCrvOrig1->GetCurveCount() ; - int nSpanUNew = nSpanU + nDiff ; pNewSurf->Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ; // copio la parte uguale for ( int i = 0 ; i < nSpanU * nDegU + 1 ; ++i) { @@ -5155,7 +5148,6 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta } // aggiungo la parte diversa for ( int i = 0 ; i < nNewCrvs * nDegU + 1 ; ++i) { - bool bOk = false ; int nSub = i / 3 ; int nPnt = i % 3 ; if ( nSub == nNewCrvs) { @@ -5192,6 +5184,10 @@ RegolarizeBordersLocally( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, Point3d ptS2 = bpIsoEnd.first ; Vector3d vtDir1 = bpIsoStart.second - ptS1 ; Vector3d vtDir2 = bpIsoEnd.second - ptS2 ; + //double dInterpolateAngTol = 4 ; + //double dAngInterp = 0 ; + //vtDir1.GetAngle( vtDir2, dAngInterp) ; + //bool bInterpolate = dAngInterp > dInterpolateAngTol ; int nDegU, nDegV, nSpanU, nSpanV ; bool bRat, bTrimmed ;