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/SurfBezier.cpp b/SurfBezier.cpp index 91450da..fbb82b7 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -6420,6 +6420,11 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p // 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 ; pCrvEdge1->GetPointD1D2( dUCurr1, ICurve::FROM_MINUS, ptCurr1, &vtCurr1) ; vtCurr1.Normalize() ; @@ -6430,105 +6435,17 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p 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. * 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) ; - } - } + 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 - 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 ; - } - } - } #if DEBUG_SYNCLINES PtrOwner ptGeo2( CreateGeoPoint3d()) ; ptGeo2->Set( ptCurr2) ; diff --git a/Trimming.cpp b/Trimming.cpp index d18a71f..699f2e0 100644 --- a/Trimming.cpp +++ b/Trimming.cpp @@ -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 ;