From 5375752609b4f4e02c74cfa4eb3fe34aae833174 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 23 Jul 2024 11:52:43 +0200 Subject: [PATCH] EgtGeomKernel : - in CalcPocketing aggiunto un frame Locale XY per semplificazione conti e migliorata la gestione della svuotature a trapezio. --- CalcPocketing.cpp | 278 ++++++++++++++++++---------------------------- 1 file changed, 109 insertions(+), 169 deletions(-) diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 86fb4b8..393edbc 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -69,12 +69,10 @@ struct PocketParams { double dToolFeed = 1000 ; // feed del tool // ------------------------------------------------------- bool bAllClosed = true ; // flag per indicare se tutti i bordi sono chiusi + Frame3d frLocXY ; // frame per conti nel piano XY } ; static double TOL_TRAPEZOID = 50 * EPS_SMALL ; // tolleranza per casi a trapezio SpiralPocket -static int TMP_PROP_SINGLE_CURVE = 3 ; // percorso singola curva aperta ( seguendo i chiusi) -static int TMP_PROP_CRV_OPEN_SIDE = 2 ; // segmento per entrata da fuori -static int TMP_PROP_OPT_TRAPEZOID = 4 ; // caso ottimizzato Trapezio //--------------------------------------------------------------------------- @@ -1066,8 +1064,8 @@ AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite* pCompo, const PocketPara //---------------------------------------------------------------------------- static bool -ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, const Vector3d& vtN, - Vector3d& vtMidOut, bool bEndOrStart) +ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, Vector3d& vtMidOut, + bool bEndOrStart) { // controllo dei parametri if ( pCrvPath == nullptr || ! pCrvPath->IsValid()) @@ -1088,7 +1086,7 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, if ( ! PockParams.SfrLimit.IsValid()) { // aggiungo al ritorno l'uscita pCrvPath->AddLine( ptOut, bEndOrStart) ; - pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out + pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out pCrvPath->SetCurveTempParam( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), GetMinFeed( PockParams) , 0) ; // Feed minima return true ; } @@ -1099,14 +1097,6 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, // Offset della regione pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ; - // creo sistema di riferimento locale per piano XY - Point3d ptFr ; pCrvPath->GetStartPoint( ptFr) ; - Frame3d frLoc ; - if ( ! frLoc.Set( ptFr, vtN)) - return false ; - - // porto la superficie limite in questo frame - pSfrLimit->ToLoc( frLoc) ; // ruoto il versore di uscita cercando un'entrata valida Vector3d vtRotMidOut = vtMidOut ; @@ -1115,19 +1105,17 @@ ExtendPathOnOpenEdge( ICurveComposite* pCrvPath, const PocketParams& PockParams, PtrOwner pCrvToolShape( CreateCurveArc()) ; if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptOut, Z_AX, PockParams.dRad)) return false ; - // porto la curva nel frame locale - pCrvToolShape->ToLoc( frLoc) ; // controllo l'intersezione ( pSfrLimit e pCrvToolShape sono nel piano XY) CRVCVECTOR ccClass ; if ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) { // aggiungo al ritorno l'uscita pCrvPath->AddLine( ptOut, bEndOrStart) ; - pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out + pCrvPath->SetCurveTempProp( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out pCrvPath->SetCurveTempParam( ( bEndOrStart ? pCrvPath->GetCurveCount() - 1 : 0), GetMinFeed( PockParams) , 0) ; // Feed minima return true ; } - vtRotMidOut.Rotate( vtN, - ANG_RIGHT) ; + vtRotMidOut.Rotate( Z_AX, - ANG_RIGHT) ; ptOut = ptMidOpen + vtRotMidOut * ( PockParams.dRad + PockParams.dOpenMinSafe) ; } @@ -1814,13 +1802,17 @@ ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo) //---------------------------------------------------------------------------- static bool -AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, bool bCalcFeed) +AdjustBorderCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, bool bCalcFeed) { /* sistemazione punto di inizio, segmento per LeadIn, e Feed ( Se la curva è chiusa, allora si può cambiare il punto d'inizio) */ + // se non ho curve, allora non faccio nulla + if ( vCrvCompo.empty()) + return true ; + // controllo validità delle curve for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid()) @@ -1835,8 +1827,6 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, pSfrLimit.Set( PockParams.SfrLimit.Clone()) ; if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid()) return false ; - // effettuo un Offset della regione, tutto ciò che dista più del raggio utensile non la rovina - pSfrLimit->Offset( PockParams.dRad - 250 * EPS_SMALL, ICurve::OFF_FILLET) ; // c'è un offset radiale, quindi tengo tolleranza alta } // per ogni curva signola, aggiungo l'entrata da fuori se ammissibile @@ -1882,7 +1872,7 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, } if ( bAllowLeadIn) { // se ammessa entrata da fuori vCrvCompo[i]->AddLine( ptFall, false) ; - vCrvCompo[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out + vCrvCompo[i]->SetCurveTempProp( 0, TEMP_PROP_OUT_START, 0) ; // nProp 2 per le curve LeadIn/Out vCrvCompo[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed massima break ; // interrompo a prescindere l'iterazione per i punti iniziali } @@ -1904,7 +1894,7 @@ AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams, GetFeedForParam( 2 * dMaxOffs, PockParams, dFeed) ; AssignCustomFeed( vCrvCompo[i], PockParams, dFeed) ; // imposto il flag di curva singola - vCrvCompo[i]->SetTempProp( TMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola + vCrvCompo[i]->SetTempProp( TEMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola } } @@ -2264,7 +2254,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams, ICRVCOMP if ( ! ChainCompoCurves( vCrvCompoRes)) return false ; // determino ora il punto di inizio, il tratto per il LeadIn e la Feed delle curve singole - if ( ! AdjustOpenCurves( vCrvCompoRes, PockParams, true)) + if ( ! AdjustBorderCurves( vCrvCompoRes, PockParams, true)) return false ; // se ho rimosso tutti i Chunk con una singola curva, allora ho terminato la svuotatura @@ -2289,7 +2279,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams, ICRVCOMP //---------------------------------------------------------------------------- static bool GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOtherCrv, - const Frame3d& frPocket, const PocketParams& PockParams, Point3d& ptMid, Vector3d& vtMidOrt) + const PocketParams& PockParams, Point3d& ptMid, Vector3d& vtMidOrt) { // recupero il vettore estrusione Vector3d vtExtr = Z_AX ; @@ -2386,14 +2376,6 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth ptFirstOpenValid = ptMid ; vtFirstOpenValid = vtMidOrt ; } - // controllo se questa quantità è effettivamente fuori dal grezzo - // ( privilegio i lati aperti che sono effettivamente sul bordo del grezzo) - // punto iniziale nel sistema di riferimento globale - Point3d ptStart ; pCompoClone->GetStartPoint( ptStart) ; - ptStart.ToGlob( frPocket) ; - // vettore d'uscita nel sistema di riferimento globale - Vector3d vtMidOut = vtMidOrt ; - vtMidOut.ToGlob( frPocket) ; } } dLenPrev = dLen ; @@ -2419,13 +2401,12 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth //---------------------------------------------------------------------------- static bool -SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const Frame3d& frPocket, - const PocketParams& PockParams, ICurveComposite* pCrvCompo, Point3d& ptStart, +SetSpecialPtStartForOpenEdges( const ICurveComposite* pCrvOrig, const PocketParams& PockParams, + ICurveComposite* pCrvCompo, Point3d& ptStart, Vector3d& vtMidOut, bool& bMidOut) { // controllo dei parametri if ( pCrvOrig == nullptr || ! pCrvOrig->IsValid() || - ! frPocket.IsValid() || pCrvCompo == nullptr || ! pCrvCompo->IsValid()) return false ; @@ -2559,8 +2540,8 @@ AssignOpenCloseTmpPropToFirstOffsCurve( ICurveComposite* pCrv, const PocketParam //---------------------------------------------------------------------------- static bool SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, const ISurfFlatRegion* pSrfToWork, - const Point3d& ptEndPrec, const Frame3d& frPocket, Point3d& ptStart, - Vector3d& vtMidOut, bool& bMidOut, int nOffs, const ICurveComposite* pCrvOrig) + const Point3d& ptEndPrec, Point3d& ptStart, Vector3d& vtMidOut, bool& bMidOut, + int nOffs, const ICurveComposite* pCrvOrig) { // ============================= INFO ============================================================== // pCrvOffsAct -> Curva di Offset su cui cercare ptStart, vtMidOut, bMidOpen @@ -2678,10 +2659,10 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, if ( nOffs == 1 && pCrvOrig != nullptr && pCrvOrig->IsValid()) { // in questo caso le curve a fagiolo dei lati aperti a sinistra e a destra potrebbero // intersecarsi tra loro -> risulta difficile calcolare il versore direzione d'uscita - bOK = SetSpecialPtStartForOpenEdges( pCrvOrig, frPocket, PockParams, pCrv, ptStart, vtMidOut, bMidOut) ; + bOK = SetSpecialPtStartForOpenEdges( pCrvOrig, PockParams, pCrv, ptStart, vtMidOut, bMidOut) ; } if ( ! bOK) /* ( 2.2 ) */ - bMidOut = GetParamOnOpenSide( pCrv, vOtherCrv, frPocket, PockParams, ptStart, vtMidOut) ; + bMidOut = GetParamOnOpenSide( pCrv, vOtherCrv, PockParams, ptStart, vtMidOut) ; } if ( bMidOut) { // se ho trovato e valido, allora imposto il punto inziale trovato const double LEN_OUT = 5 ; @@ -2705,9 +2686,8 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, //---------------------------------------------------------------------------- static bool SetAdvancedPtStartForPath( ICRVCOMPOPOVECTOR& vCrvOffsAct, const PocketParams& PockParams, const ISurfFlatRegion* pSrfToWork, - const Point3d& ptEndPrec, const Frame3d& frPocket, Point3d& ptStart, - Vector3d& vtMidOut, bool& bMidOut, int& nIndex, int nOffs, - ICRVCOMPOPOVECTOR& vCrvOrigChunkLoops) + const Point3d& ptEndPrec, Point3d& ptStart, Vector3d& vtMidOut, + bool& bMidOut, int& nIndex, int nOffs, ICRVCOMPOPOVECTOR& vCrvOrigChunkLoops) { // controllo dei parametri for ( int i = 0 ; i < int( vCrvOffsAct.size()) ; ++ i) @@ -2725,9 +2705,8 @@ SetAdvancedPtStartForPath( ICRVCOMPOPOVECTOR& vCrvOffsAct, const PocketParams& P Point3d ptStart_first ; for ( int i = 0 ; i < int( vCrvOffsAct.size()) ; ++ i) { // cambio il suo punto d'inizio dell'Offset attuale - if ( SetPtStartForPath( vCrvOffsAct[i], PockParams, pSrfToWork, ptEndPrec, frPocket, ptStart, - vtMidOut, bMidOut, nOffs, - ( int( vCrvOrigChunkLoops.size()) < i) ? Get( vCrvOrigChunkLoops[i]) : nullptr)) + if ( SetPtStartForPath( vCrvOffsAct[i], PockParams, pSrfToWork, ptEndPrec, ptStart, vtMidOut, + bMidOut, nOffs, ( int( vCrvOrigChunkLoops.size()) < i) ? Get( vCrvOrigChunkLoops[i]) : nullptr)) vCrvOffsAct[i]->GetStartPoint( ptStart) ; else return false ; @@ -2776,7 +2755,7 @@ GetOptCrvIndex( const ISurfFlatRegion* pSfrOrig, const ISurfFlatRegion* pSfrChun // se la superficie originale ha un solo Chunk, allora le curve originali sono già trovate for ( int l = 0 ; l < pSfrOrig->GetLoopCount( 0) ; ++ l) - vCrvOrig.emplace_back( ConvertCurveToComposite( pSfrOrig->GetLoop( 0, l))) ; // sono inizializzate... + vCrvOrig.emplace_back( ConvertCurveToComposite( pSfrOrig->GetLoop( 0, l))) ; if ( pSfrOrig->GetChunkCount() == 1) return true ; @@ -3227,7 +3206,12 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr // se la curva è già un trapezio, non sempre devo adattarla... Point3d pt ; Vector3d vtDir, vtB2, vtOtherDir ; if ( pCrvCompo->IsATrapezoid( 100 * EPS_SMALL, pt, vtDir, vtOtherDir, vtB2)) { - pCrvTrap->AddCurve( pCrvCompo->Clone()) ; + // data la tolleranza, creo la curva a trapezio dai 4 punti + pCrvTrap->AddPoint( pt) ; + pCrvTrap->AddLine( pt + vtDir) ; + pCrvTrap->AddLine( pt + vtOtherDir + vtB2) ; + pCrvTrap->AddLine( pt + vtOtherDir) ; + pCrvTrap->Close() ; // se parallelogramma scelgo come base i lati lunghi Vector3d vtL2( - vtDir + vtOtherDir + vtB2) ; if ( AreSameOrOppositeVectorApprox( vtOtherDir, vtL2)) { @@ -3237,13 +3221,6 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr vtDir.Normalize() ; Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ; dPocketSize = vtOrtho.Len() ; - // eventuale approssimazione della curva con polyline per ottenere la stessa curva calcolata in ICurveComposite::IsATrapezoid - if ( pCrvCompo->GetCurveCount() > 4) { - PolyLine PL ; - if ( ! pCrvCompo->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) - return false ; - pCrvTrap->FromPolyLine( PL) ; - } if ( ! CalcTrapezoidSpiralLocalFrame( pCrvTrap, vtDir, frTrap)) return false ; bool bBaseOpen = false ; @@ -6064,7 +6041,7 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con //---------------------------------------------------------------------------- static bool CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, const int nOffsCount, - const int nIter, const Vector3d& vtN, const PocketParams& PockParams, bool& bInsert) + const int nIter, const PocketParams& PockParams, bool& bInsert) { // controllo dei parametri @@ -6124,7 +6101,7 @@ CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, c return true ; // frame locale, recupero DimX e DimY - Frame3d frLoc ; frLoc.Set( ptC, vtN, vtX) ; + Frame3d frLoc ; frLoc.Set( ptC, Z_AX, vtX) ; if ( ! frLoc.IsValid()) return true ; BBox3d bBox ; @@ -6163,18 +6140,11 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int if ( IsNull( pSrfToWork) || pSrfToWork->GetChunkCount() == 0) return false; - // porto il Chunk c-esimo nel sistema di riferimento locale - Vector3d vtExtr = pSrfToWork->GetNormVersor() ; - Point3d ptCen ; pSrfToWork->GetCentroid( ptCen) ; - Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ; - - - // CONTROLLO PER CASI OTTIMIZZATI + // ---------------------------------- Casi ottimizzati ---------------------------------- bool bHasIsland = ( pSrfPock->GetLoopCount( 0) > 1) ; // se non ho isole e curva valida allora controllo casi ottimizzati if ( ! PockParams.bAvoidOpt && ! bHasIsland && ( ! vCrvOrigChunkLoops.empty()) && ! IsNull( vCrvOrigChunkLoops[0])) { - // --------------------------- caso spirale --------------------------------------- PtrOwner pCrvBorder( ConvertCurveToComposite( pSrfPock->GetLoop( 0, 0))) ; if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid()) @@ -6209,7 +6179,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int else return true ; } - // -------------------------- caso trapezoide --------------------------------------- PtrOwner pCrvTrap( CreateCurveComposite()) ; if ( IsNull( pCrvTrap)) @@ -6217,17 +6186,13 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int Frame3d frTrap ; double dPocketSize ; int nBase, nSecondBase ; - vCrvOrigChunkLoops[0]->ToLoc( frPocket) ; if ( ! GetTrapezoidFromShape( vCrvOrigChunkLoops[0], pCrvTrap, frTrap, PockParams, dPocketSize, nBase, nSecondBase)) return false ; - vCrvOrigChunkLoops[0]->ToGlob( frPocket) ; if ( pCrvTrap->IsValid()) { - pCrvTrap->SetExtrusion( vtExtr) ; + pCrvTrap->SetExtrusion( Z_AX) ; if ( nReg == 0) { CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, PockParams, pMCrv, pRCrv, bOptimizedTrap) ; if ( bOptimizedTrap) { - pMCrv->ToGlob( frPocket) ; - pRCrv->ToGlob( frPocket) ; nReg = 1 ; return true ; } @@ -6238,9 +6203,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int } - // porto la superficie nel frame corrente - pSrfToWork->ToLoc( frPocket) ; - // ciclo di offset verso l'interno const int MAX_ITER = 1000 ; int nIter = 0 ; @@ -6294,7 +6256,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int pCrvCompoBorder->Invert() ; // controllo quali regioni di Offset possono essere sostituite bool bInsert = true ; - if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, int( vOffs.size()), nIter, vtExtr, PockParams, bInsert)) + if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, int( vOffs.size()), nIter, PockParams, bInsert)) return false ; if ( bInsert) vOffs.emplace_back( Release( pCrvCompoBorder)) ; @@ -6335,29 +6297,25 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int return true ; // cambio il punto iniziale della prima Curva di Offset - Point3d ptRef = PockParams.ptEnd ; ptRef.ToLoc( frPocket) ; + Point3d ptRef = PockParams.ptEnd ; Point3d ptNewStart ; - if ( ! IsNull( vCrvOrigChunkLoops[0])) - vCrvOrigChunkLoops[0]->ToLoc( frPocket) ; // Se ho come lavorazione uno SpiralIn posso poter entrare dalle isole aperte... int nIndexSwap = 0 ; // indice del vettore di curve per identificare la curva su cui entrare if ( PockParams.nType == POCKET_SPIRALIN) { - if ( SetAdvancedPtStartForPath( vOffsFirstCurve, PockParams, pSrfToWork, ptRef, frPocket, - ptStart, vtMidOut, bMidOut, nIndexSwap, int( vOffs.size()), vCrvOrigChunkLoops)) + if ( SetAdvancedPtStartForPath( vOffsFirstCurve, PockParams, pSrfToWork, ptRef, ptStart, + vtMidOut, bMidOut, nIndexSwap, int( vOffs.size()), vCrvOrigChunkLoops)) vOffsFirstCurve[nIndexSwap]->GetStartPoint( ptNewStart) ; else return false ; } else { - if ( SetPtStartForPath( vOffs[0], PockParams, pSrfToWork, ptRef, frPocket, ptStart, vtMidOut, bMidOut, + if ( SetPtStartForPath( vOffs[0], PockParams, pSrfToWork, ptRef, ptStart, vtMidOut, bMidOut, int( vOffs.size()), vCrvOrigChunkLoops[0])) vOffs[0]->GetStartPoint( ptNewStart) ; else return false ; } - if ( ! IsNull( vCrvOrigChunkLoops[0])) - vCrvOrigChunkLoops[0]->ToGlob( frPocket) ; // se richiesta inversione for ( int i = 0 ; i < int( vOffs.size()) && PockParams.bInvert ; ++ i) @@ -6387,8 +6345,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int return false ; // controllo eventuali parti non svuotate... - if ( ! IsNull( vCrvOrigChunkLoops[0])) - vCrvOrigChunkLoops[0]->ToLoc( frPocket) ; PtrOwner pSrfToCut( CreateSurfFlatRegion()) ; if ( GetUnclearedRegion( vOffsFirstCurve, vOffs, vLinks, vCrvOrigChunkLoops[0], PockParams, pSrfToCut)) { // Modifico i percorsi @@ -6422,15 +6378,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int } // setto estrusione - pMCrv->SetExtrusion( vtExtr) ; - - // riporto tutto nel sistema di riferimento originale - pMCrv->ToGlob( frPocket) ; - ptStart.ToGlob( frPocket) ; - vtMidOut.ToGlob( frPocket) ; - if ( ! IsNull( vCrvOrigChunkLoops[0])) - vCrvOrigChunkLoops[0]->ToGlob( frPocket) ; - + pMCrv->SetExtrusion( Z_AX) ; return true ; } @@ -6960,10 +6908,10 @@ AddSpiralIn( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, if ( bOptimizedTrap) { // se caso a trapezio AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, PockParams) ; AssignFeedSpiralOpt( 1, PockParams, pMCrv) ; - pMCrv->SetTempProp( TMP_PROP_OPT_TRAPEZOID, 0) ; + pMCrv->SetTempProp( TEMP_PROP_OPT_TRAPEZOID, 0) ; } else if ( bSomeOpen) { // se presenza di lati aperti validi - if ( ! ExtendPathOnOpenEdge( pMCrv, PockParams, pSrfChunk->GetNormVersor(), vtMidOut, false)) + if ( ! ExtendPathOnOpenEdge( pMCrv, PockParams, vtMidOut, false)) return false ; } @@ -7026,7 +6974,7 @@ AddSpiralOut( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, if ( bOptimizedTrap) { // se caso a trapezio AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, PockParams) ; AssignFeedSpiralOpt( 1, PockParams, pMCrv) ; - pMCrv->SetTempProp( TMP_PROP_OPT_TRAPEZOID, 0) ; + pMCrv->SetTempProp( TEMP_PROP_OPT_TRAPEZOID, 0) ; } // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) @@ -7064,7 +7012,7 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams& pSfrLimit.Set( PockParams.SfrLimit.Clone()) ; if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid()) return false ; - pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ; + pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - 50 * EPS_SMALL, ICurve::OFF_FILLET) ; } // vettore delle curve chiuse Offsettate @@ -7080,8 +7028,8 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams& // recupero i tratti con proprietà uniformi ICRVCOMPOPOVECTOR vpCrvs ; GetHomogeneousParts( pCrvLoop, PockParams, vpCrvs) ; - if ( vpCrvs.size() > 1) { // unisco il primo e l'ultimo se estremi compatibili - // NB. GetHomogeneousParts() cambia il punto di inizio nel lato chiuso più lungo ( se presente) + if ( vpCrvs.size() > 1) { + // unisco il primo e l'ultimo se estremi compatibili Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ; Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ; if ( AreSamePointApprox( ptS, ptE)) { @@ -7089,11 +7037,20 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams& vpCrvs.erase( vpCrvs.end() - 1) ; } } + // le isole aperte vanno percorse + bool bOpenIsland = ( nL > 0 && int( vpCrvs.size()) == 1 && + vpCrvs[0]->GetTempProp() == TEMP_PROP_OPEN_EDGE) ; // scorro tutti i tratti chiusi e calcolo l'Offset for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - if ( vpCrvs[i]->GetTempProp( 0) == 0) { // se tratto chiuso... - OffsetCurve OffsCrv ; // con offset verso l'interno - if ( OffsCrv.Make( vpCrvs[i], - PockParams.dRad - PockParams.dRadialOffset, ICurve::OFF_FILLET)) { + // se tratto chiuso o isola aperta + if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE || bOpenIsland) { + // Offset per le curve + OffsetCurve OffsCrv ; + double dOffs = - PockParams.dRad - PockParams.dRadialOffset ; + // se isole, l'Offset è di segno opposto + if ( nL > 0) + dOffs *= -1 ; + if ( OffsCrv.Make( vpCrvs[i], dOffs, ICurve::OFF_FILLET)) { PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; while ( ! IsNull( pOffLongestCrv)) { // recupero solo i tratti di curva al di fuori della superficie limite @@ -7129,7 +7086,7 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams& if ( ! ChainCompoCurves( vClosedOffs)) return false ; // determino ora il punto di inizio, il tratto per il LeadIn - if ( ! AdjustOpenCurves( vClosedOffs, PockParams, false)) + if ( ! AdjustBorderCurves( vClosedOffs, PockParams, false)) return false ; // Calcolo ora le Feed e restituisco le curve ottenute @@ -7149,25 +7106,19 @@ GetZigZagOneWayBorderCrvs( const ISurfFlatRegion* pSfrPock, const PocketParams& //---------------------------------------------------------------------------- static bool -AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvCompoRes) +AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, + ICRVCOMPOPOVECTOR& vCrvCompoRes) { // Offset della regione per curva ZigZag double dOffs = PockParams.dRad + PockParams.dRadialOffset ; - // determino il sistema di riferimento in base alla svuotatura - Frame3d frPocket ; - Point3d ptCen ; pSrfPock->GetCentroid( ptCen) ; - if ( ! frPocket.Set( ptCen, pSrfPock->GetNormVersor()) || - ! frPocket.Rotate( ptCen, pSrfPock->GetNormVersor(), PockParams.dAngle)) - return false ; - // ciclo su tutti i chunks della superficie originale for ( int nC = 0 ; nC < pSrfPock->GetChunkCount() ; ++ nC) { // creo la regione per il percorso a ZigZag ( mediante primo Offset) portandola // nel sistema di riferimento creato PtrOwner pSrfZigZag( pSrfPock->CloneChunk( nC)) ; - if ( ! pSrfZigZag->ToLoc( frPocket) || ! pSrfZigZag->Offset( - dOffs, ICurve::OFF_FILLET)) + if ( ! pSrfZigZag->Offset( - dOffs, ICurve::OFF_FILLET)) return false ; // vettore con i percorsi a ZigZag relativi al Chunk nC-esimo ICRVCOMPOPOVECTOR vpCrvs ; @@ -7193,8 +7144,6 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con for ( int nU = 0 ; nU < int( vpCrvs.size()) ; ++ nU) { // pulisco le tempProp ResetCurveTempProps( vpCrvs[nU]) ; - // porto la curva in globale - vpCrvs[nU]->ToGlob( frPocket) ; // se il Chunk originale aveva lati aperti, estendo il percorso a ZigZag if ( ! bIsChunkClosed) { bool bIsInside = false ; @@ -7205,13 +7154,13 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con ptStart.Translate( 0.25 * PockParams.dRad * vtStart) ; double dMinDist = max( 0., - PockParams.dRadialOffset) ; if ( IsPointInsideSurfFr( ptStart, pSfrOrig, dMinDist, bIsInside) && ! bIsInside) - ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, pSrfPock->GetNormVersor(), vtStart, false) ; + ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, vtStart, false) ; // controllo se il punto finale è esterno alla superficie originale Point3d ptEnd ; vpCrvs[nU]->GetEndPoint( ptEnd) ; Vector3d vtEnd ; vpCrvs[nU]->GetEndDir( vtEnd) ; - ptEnd.Translate( ( 0.25 * PockParams.dRad) * vtEnd) ; + ptEnd.Translate( 0.25 * PockParams.dRad * vtEnd) ; if ( IsPointInsideSurfFr( ptEnd, pSfrOrig, dMinDist, bIsInside) && ! bIsInside) - ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, pSrfPock->GetNormVersor(), vtEnd, true) ; + ExtendPathOnOpenEdge( vpCrvs[nU], PockParams, vtEnd, true) ; } // inserisco le curve nel vettore risultante vCrvCompoRes.emplace_back( Release( vpCrvs[nU])) ; @@ -7220,9 +7169,8 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con vpCrvs.clear() ; } - // se richiesto, aggiungo le curve chiuso di Bordo + // se richiesto, aggiungo le curve chiuse di Bordo if ( PockParams.bAllowZigZagOneWayBorders) { - ICRVCOMPOPOVECTOR vCrvOffs ; // recupero il Chunk nC-esimo PtrOwner pSfrChunk( pSrfPock->CloneChunk( nC)) ; if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid() || @@ -7319,42 +7267,21 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con PtrOwner pSrfToPock( pSrfPock->Clone()) ; if ( IsNull( pSrfToPock)) return false ; - - // creo le regioni ideali -------------------------------------------- - // creo un frame di riferimento della svuotatura - Frame3d frLoc ; - Point3d ptC ; pSrfToPock->GetCentroid( ptC) ; - Vector3d vtN = pSrfToPock->GetNormVersor() ; - frLoc.Set( ptC, vtN) ; - pSrfToPock->ToLoc( frLoc) ; - ISURFFRPOVECTOR vSrfFlat ; // vettore delle regioni ideali + // vettore delle regioni ideali + ISURFFRPOVECTOR vSrfFlat ; if ( ! OptimizeChunkOneWay( pSrfToPock, vSrfFlat)) return false ; - // riporto le superfici ideali nel sistema di riferimento globale ( Ogni chunk verrà poi messo nel suo frame) - for ( int i = 0 ; i < int( vSrfFlat.size()) ; ++ i) - vSrfFlat[i]->ToGlob( frLoc) ; - // ------------------------------------------------------------------ - // scorro le regioni ideali for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) { - // copio la superficie ideale - PtrOwner pSrfIdeal( vSrfFlat[nIs]->Clone()) ; - if ( IsNull( pSrfIdeal)) + // copio la superficie ideale ed effettuo il primo Offset + PtrOwner pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ; + if ( IsNull( pSrfIdeal) || ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET)) return false ; - // effettuo Offset interno - if ( ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET)) - return false ; - - // creo un frame coerente con i parametri - Frame3d frPocket ; - Point3d ptCen ; pSrfIdeal->GetCentroid( ptCen) ; - frPocket.Set( ptCen, pSrfIdeal->GetNormVersor()) ; - frPocket.Rotate ( ptCen, pSrfIdeal->GetNormVersor(), PockParams.dAngle) ; - pSrfIdeal->ToLoc( frPocket) ; + // recupero il Box della superficie attuale da svuotare BBox3d b3Pocket ; pSrfIdeal->GetLocalBBox( b3Pocket) ; Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; @@ -7417,7 +7344,6 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con pCrvSegCompo->AddCurve( Release( pCrvSeg)) ; // calcolo la Feed AssignFeedZigZagOneWay( pCrvSegCompo, false, vCrvNull, vLineUnder, vCrvCompoNull, PockParams) ; - pCrvSegCompo->ToGlob( frPocket) ; vCrvCompoRes.emplace_back( Release( pCrvSegCompo)) ; } } @@ -7457,47 +7383,61 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double myParams.bAvoidOpt = bAvoidOpt ; if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) myParams.SfrLimit.CopyFrom( pSfrLimit) ; - - // ------------ gestione dei lati aperti ------------------- - // creo un sistema di riferimento locale Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ; - Vector3d vtN = pSfr->GetNormVersor() ; - Frame3d frLoc ; - if ( ! frLoc.Set( ptCenter, vtN)) + if ( ! myParams.frLocXY.Set( ptCenter, pSfr->GetNormVersor()) || + ! myParams.frLocXY.Rotate( ptCenter, pSfr->GetNormVersor() , myParams.dAngle)) return false ; + // porto la superficie da svuotare in tale sistema PtrOwner pSfrAdj( pSfr->Clone()) ; - if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( frLoc)) + if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( myParams.frLocXY)) return false ; // porto la superficie limite ( se valida) in tale sistema if ( myParams.SfrLimit.IsValid()) - myParams.SfrLimit.ToLoc( frLoc) ; + myParams.SfrLimit.ToLoc( myParams.frLocXY) ; + + // ------------ gestione dei lati aperti ------------------- // modifico la superficie da svuotare estendendo i lati aperti bool bSkipPocket = false ; // se la superficie si svuota mediante curve singole di primo Offset dei chiusi if ( ! ModifySurfByOpenEdges( pSfrAdj, myParams, vCrvCompoRes, bSkipPocket)) return false ; - // se ottengo delle curve si svuotatura di primo Offset, le riporto in globale - for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i) - vCrvCompoRes[i]->ToGlob( frLoc) ; - if ( bSkipPocket) // se tali curva rimuovono tutta la regione, allora non faccio nulla + // se le curve di primo offset che ho ottenuto, svuotano tutta la superficie, allora ho finito + if ( bSkipPocket) { + // riporto le curve in Globale + for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i) + vCrvCompoRes[i]->ToGlob( myParams.frLocXY) ; return true ; - // riporto tutto nel frame originale - pSfrAdj->ToGlob( frLoc) ; - if ( myParams.SfrLimit.IsValid()) - myParams.SfrLimit.ToGlob( frLoc) ; + } + // porto una copia della superficie originale nel frame creato + PtrOwner pSfr_Loc( CloneSurfFlatRegion( pSfr)) ; + if ( IsNull( pSfr_Loc) || ! pSfr_Loc->IsValid() || ! pSfr_Loc->ToLoc( myParams.frLocXY)) + return false ; // ------------ calcolo delle curve elementari della superficie ------------------- switch ( nType) { case POCKET_ZIGZAG : - return AddZigZag( pSfrAdj, pSfr, myParams, vCrvCompoRes) ; + if ( ! AddZigZag( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes)) + return false ; + break ; case POCKET_ONEWAY : - return AddOneWay( pSfrAdj, pSfr, myParams, vCrvCompoRes) ; + if ( ! AddOneWay( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes)) + return false ; + break ; case POCKET_SPIRALIN : - return AddSpiralIn( pSfrAdj, pSfr, myParams, vCrvCompoRes) ; + if ( ! AddSpiralIn( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes)) + return false ; + break ; case POCKET_SPIRALOUT : - return AddSpiralOut( pSfrAdj, pSfr, myParams, vCrvCompoRes) ; + if ( ! AddSpiralOut( pSfrAdj, pSfr, myParams, vCrvCompoRes)) + return false ; + break ; } - return false ; + + // riporto tutte le curve ottenute in globale + for ( int i = 0 ; i < int( vCrvCompoRes.size()) ; ++ i) + vCrvCompoRes[i]->ToGlob( myParams.frLocXY) ; + + return true ; } //----------------------------------------------------------------------------