From a2bcc4d6821321c61b9d240d7dd488ca38beaf6c Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Fri, 22 May 2026 10:41:09 +0200 Subject: [PATCH] EgtGeomKernel : - migliorata funzione per l'interpolazione di direzioni per la lavorazione di trimming. --- Trimming.cpp | 169 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 42 deletions(-) diff --git a/Trimming.cpp b/Trimming.cpp index 699f2e0..e008dbb 100644 --- a/Trimming.cpp +++ b/Trimming.cpp @@ -3533,10 +3533,11 @@ IsBorderAButtonHole( const PolyLine& PL, double dLinTol, double dAngTol, Frame3d //----------------------------------------------------------------------------- static bool InterpolateSyncCurvesOnEndGuidePoints( const ICurveComposite* pGuide, const ICurveComposite* pOtherGuide, - const Plane3d& plStart, const Plane3d& plEnd, double dLinTol, - BIPNTVECTOR& vBiPts) + const Plane3d& plStart, const Plane3d& plEnd, const Vector3d vtAuxStart, const Vector3d vtAuxEnd, + double dLinTol, BIPNTVECTOR& vBiPts) { vBiPts.clear() ; + const double dLinAngTol = 15 * EPS_SMALL ; // tolleranza sulla lunghezza della corda dell'angolo di tolleranza // Verifico che le curve siano valide if ( pGuide == nullptr || ! pGuide->IsValid() || @@ -3566,52 +3567,134 @@ InterpolateSyncCurvesOnEndGuidePoints( const ICurveComposite* pGuide, const ICur // Interpolo le normali dei piani rispetto a tale valore Vector3d vtN = Media( plStart.GetVersN(), plEnd.GetVersN(), dInterPar) ; vtN.Normalize() ; + Vector3d vtAux = Media( vtAuxStart, vtAuxEnd, dInterPar) ; vtAux.Normalize() ; // Definisco il piano di intersezione Point3d ptCurr ; if ( ! pCrv->GetEndPoint( ptCurr)) return false ; + + // con i piani #if DEBUG_SYNC_INTERPOLATION Frame3d frPl ; frPl.Set( ptCurr, vtN) ; PtrOwner frCurr( CreateGeoFrame3d()) ; frCurr->Set( frPl) ; VT.emplace_back( Release( frCurr)) ; VC.emplace_back( WHITE) ; - SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ; + SaveGeoObj( VT, VC, "C:\\Temp\\trimming\\interpolate\\SyncLinesPlanes.nge") ; #endif // Recupero il parametro di intersezione tra la curva e il piano - #if 0 - VT.clear() ; VC.clear() ; - PtrOwner PT( CreateGeoPoint3d()) ; PT->Set( ptCurr) ; - VT.emplace_back( Release( PT)) ; - VC.emplace_back( AQUA) ; - PtrOwner VECT( CreateGeoVector3d()) ; VECT->Set( vtN) ; - VECT->ChangeBase( ptCurr) ; - PtrOwner pArc( CreateCurveArc()) ; pArc->Set( ptCurr, vtN, 1000.) ; - PtrOwner pSfrPlane( CreateSurfFlatRegion()) ; - pSfrPlane->AddExtLoop( Release( pArc)) ; - VT.emplace_back( Release( pSfrPlane)) ; - VC.emplace_back( Color( 0., 0., 0., .5)) ; - VT.emplace_back( Release( VECT)) ; - VC.emplace_back( BLUE) ; - VT.emplace_back( pOtherGuide->Clone()) ; - VC.emplace_back( WHITE) ; - SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ; - #endif - IntersCurvePlane IntCP( *pOtherGuide, ptCurr, vtN) ; - if ( IntCP.GetIntersCount() == 0) - return false ; // ambiguità - // Recupero il punto della prima intersezione trovata - Point3d ptInt ; - double dPar ; - if ( ! IntCP.GetIntersPointNearTo( ptCurr, ptInt, dPar)) - return false ; #if DEBUG_SYNC_INTERPOLATION - PtrOwner ptG( CreateGeoPoint3d()) ; ptG->Set( ptInt) ; - VT.emplace_back( Release( ptG)) ; - VC.emplace_back( WHITE) ; - SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ; + if ( false) { + VT.clear() ; VC.clear() ; + PtrOwner PT( CreateGeoPoint3d()) ; PT->Set( ptCurr) ; + VT.emplace_back( Release( PT)) ; + VC.emplace_back( AQUA) ; + PtrOwner VECT( CreateGeoVector3d()) ; VECT->Set( vtN) ; + VECT->ChangeBase( ptCurr) ; + PtrOwner pArc( CreateCurveArc()) ; pArc->Set( ptCurr, vtN, 1000.) ; + PtrOwner pSfrPlane( CreateSurfFlatRegion()) ; + pSfrPlane->AddExtLoop( Release( pArc)) ; + VT.emplace_back( Release( pSfrPlane)) ; + VC.emplace_back( Color( 0., 0., 0., .5)) ; + VT.emplace_back( Release( VECT)) ; + VC.emplace_back( BLUE) ; + VT.emplace_back( pOtherGuide->Clone()) ; + VC.emplace_back( WHITE) ; + SaveGeoObj( VT, VC, "C:\\Temp\\trimming\\interpolate\\SyncLinesPlanes.nge") ; + } #endif - // Memorizzo tale punto - vBiPts.emplace_back( make_pair( ptCurr, ptInt)) ; + + IntersCurvePlane IntCP( *pOtherGuide, ptCurr, vtN) ; + bool bFound = false ; + if ( IntCP.GetIntersCount() != 0) { + // Recupero il punto della prima intersezione trovata + Point3d ptIntClosest ; + double dPar ; + IntCP.GetIntersPointNearTo( ptCurr, ptIntClosest, dPar) ; + // verifico che sia allineato con la direzione che dovrebbe avere + Vector3d vtDir = ptIntClosest - ptCurr ; + vtDir.Normalize() ; + double dDiff = (vtDir - vtAux).Len() ; + if ( dDiff < dLinAngTol) { + #if DEBUG_SYNC_INTERPOLATION + PtrOwner ptG( CreateGeoPoint3d()) ; ptG->Set( ptIntClosest) ; + VT.emplace_back( Release( ptG)) ; + VC.emplace_back( WHITE) ; + SaveGeoObj( VT, VC, "C:\\Temp\\trimming\\interpolate\\SyncLinesPlanes.nge") ; + #endif + //Memorizzo tale punto + vBiPts.emplace_back( make_pair( ptCurr, ptIntClosest)) ; + bFound = true ; + } + else if ( IntCP.GetIntersCount() > 1) { + double dMinDiff = INFINITO ; + Point3d ptBest ; + for ( int j = 0 ; j < IntCP.GetIntersCount() ; ++j) { + IntCrvPlnInfo icpi ; IntCP.GetIntCrvPlnInfo( j, icpi) ; + Point3d ptInt = icpi.Ici->ptI ; + double dDiff = ( ptInt - ptCurr).Len() ; + if ( dDiff < dMinDiff) { + dMinDiff = dDiff ; + ptBest = ptInt ; + } + } + if ( dMinDiff < dLinAngTol) + bFound = true ; + } + } + + if ( ! bFound) { + // applico la direzione desiderata nel punto corrente della guida + // calcolo la lunghezza dell'isocurva in quella zona + Point3d ptS1, ptS2 ; + pGuide->GetStartPoint( ptS1) ; + pOtherGuide->GetStartPoint( ptS2); + double dDistRef = Dist( ptS1, ptS2) ; + double dParamOther = -1. ; + int nFlag = -1 ; + Point3d ptEnd = ptCurr + (vtAux * dDistRef) ; + if ( ! DistPointCurve( ptEnd, *pOtherGuide).GetParamAtMinDistPoint( 0, dParamOther, nFlag)) + return false ; + + // nell'intorno del più vicino, cerco l'isocurva più vicina alla direzione desiderata + Point3d ptBest ; + double dMinDiff = INFINITO ; + double dSearchLen = 3. ; + double dStepLen = 0.1 ; + double dCurrLenOther ; pOtherGuide->GetLengthAtParam( dParamOther, dCurrLenOther) ; + double dLenOther ; pOtherGuide->GetLength( dLenOther) ; + dCurrLenOther -= dSearchLen ; + dCurrLenOther = Clamp( dCurrLenOther, 0., dLenOther) ; + for ( int j = 0 ; j < 2 * dSearchLen / dStepLen ; ++j) { + dCurrLenOther += j * dStepLen ; + if ( dCurrLenOther > dLenOther) + break ; + double dCurrParOther = 0 ; pOtherGuide->GetParamAtLength( dCurrLenOther, dCurrParOther) ; + Point3d ptCurrOther ; pOtherGuide->GetPointD1D2( dCurrParOther, ICurve::FROM_MINUS, ptCurrOther) ; + Vector3d vtDir = ptCurrOther - ptCurr ; vtDir.Normalize() ; + double dDiff = ( vtDir - vtAux).Len() ; + if ( dDiff < dMinDiff) { + dMinDiff = dDiff ; + ptBest = ptCurrOther ; + } + #if DEBUG_SYNC_INTERPOLATION + VT.clear() ; + VC.clear() ; + VT.emplace_back( pGuide->Clone()) ; + VC.emplace_back( BLUE) ; + VT.emplace_back( pOtherGuide->Clone()) ; + VC.emplace_back( BLUE) ; + PtrOwner vtFirst( CreateGeoVector3d()) ; vtFirst->Set( -vtN * 12, ptCurrOther) ; + VT.emplace_back( Release( vtFirst)) ; + VC.emplace_back( AQUA) ; + PtrOwner vtCurr( CreateGeoVector3d()) ; vtCurr->Set( -vtDir * 12, ptCurrOther) ; + VT.emplace_back( Release( vtCurr)) ; + VC.emplace_back( WHITE) ; + SaveGeoObj( VT, VC, "C:\\Temp\\trimming\\interpolate\\SyncLinesPlanes.nge") ; + #endif + } + if ( dMinDiff < 2 * dLinAngTol) + vBiPts.emplace_back( make_pair( ptCurr, ptBest)) ; + } } return true ; @@ -4066,18 +4149,18 @@ GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, Vector3d vtStart1, vtStart2 ; if ( ! pCompoGuide1->GetStartDir( vtStart1) || ! pCompoGuide2->GetStartDir( vtStart2)) return false ; - Vector3d vtAux = ptE1 - ptS1 ; vtAux.Normalize() ; + Vector3d vtAuxStart = ptE1 - ptS1 ; vtAuxStart.Normalize() ; Vector3d vtMTan = Media( vtStart1, vtStart2) ; vtMTan.Normalize() ; - Vector3d vtN = OrthoCompo( vtMTan, vtAux) ; vtN.Normalize() ; + Vector3d vtN = OrthoCompo( vtMTan, vtAuxStart) ; vtN.Normalize() ; Plane3d plStart ; if ( ! plStart.Set( ptS1, vtN)) return false ; Vector3d vtEnd1, vtEnd2 ; if ( ! pCompoGuide1->GetEndDir( vtEnd1) || ! pCompoGuide2->GetEndDir( vtEnd2)) return false ; - vtAux = ptE2 - ptS2 ; vtAux.Normalize() ; + Vector3d vtAuxEnd = ptE2 - ptS2 ; vtAuxEnd.Normalize() ; vtMTan = Media( vtEnd1, vtEnd2) ; vtMTan.Normalize() ; - vtN = OrthoCompo( vtMTan, vtAux) ; vtN.Normalize() ; + vtN = OrthoCompo( vtMTan, vtAuxEnd) ; vtN.Normalize() ; Plane3d plEnd ; if ( ! plEnd.Set( ptS2, vtN)) return false ; @@ -4096,13 +4179,15 @@ GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, // Curve di Sincronizzazione del Bordo 1 sul Bordo 2 BIPNTVECTOR vBiPts1 ; - if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide1, pCompoGuide2, plStart, plEnd, dMyLinTol, vBiPts1)) + if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide1, pCompoGuide2, plStart, plEnd, vtAuxStart, vtAuxEnd, dMyLinTol, vBiPts1)) return false ; + vtAuxStart *= -1 ; + vtAuxEnd *= -1 ; // Curve di Sincronizzazione del Bordo 2 sul Bordo 1 BIPNTVECTOR vBiPts2 ; - if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide2, pCompoGuide1, plStart, plEnd, dMyLinTol, vBiPts2)) - return false ; + //if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide2, pCompoGuide1, plStart, plEnd, vtAuxStart, vtAuxEnd, dMyLinTol, vBiPts2)) + // return false ; // Restituisco le Curve di Sincronizzazione // [Da Bordo 1 a Bordo 2 originale]