From 7ca922c9b6331d58af02e2776f095f479c72f928 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 7 Nov 2023 17:46:49 +0100 Subject: [PATCH] EgtMachKernel : - codice per casi ottimizzati ZigZag. --- Pocketing.cpp | 476 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 283 insertions(+), 193 deletions(-) diff --git a/Pocketing.cpp b/Pocketing.cpp index edd551d..b2dacd1 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -2436,7 +2436,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c ! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut)) return false ; - int nOff_index = int( vCrvInfo.size()) ; + int nOff_index = int( vpCrvs.size()) ; for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) { vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ; vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ; @@ -2465,6 +2465,13 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } + if ( ! pSrfForCrv->IsValid()) { + pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunkFinal)) ; + if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + } // Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove // superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e, // per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti. @@ -2581,16 +2588,15 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c bool bOptTwoOpposite = vChunkInfo[vCrvInfo[u].nChunk].bOptTwoOpposite ; // se un lato chiuso if ( nClosedSide == 1) { - // inverto il percorso + // inverto il percorso ( parto dall'aperto) pCrvCurr->Invert() ; - // verifico se attacco fuori dal grezzo + // verifico se attacco fuori dal grezzo ( allungandolo) Point3d ptStart ; pCrvCurr->GetStartPoint( ptStart) ; Vector3d vtDir ; pCrvCurr->GetStartDir( vtDir) ; - Point3d ptTest = ptStart + ( - vtDir) * - ( m_TParams.m_dDiam / 2 - dOffsOpt + dSafeZ) ; - ptTest += - vtTool * dDepth ; + Point3d ptTest = ptStart + ( - vtDir) * ( m_TParams.m_dDiam / 2 - dOffsOpt + dSafeZ) ; + ptTest.Translate( vVtTrasl[j-1]) ; double dTestElev ; // se è nel grezzo provo a ruotare di 90 gradi if ( GetElevation( m_nPhase, ptTest, vtTool, @@ -2611,6 +2617,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } } } + // Spostare dentro caso ottimizzato (?) // se due lati chiusi consecutivi o tre lati chiusi... else if (( nClosedSide == 2 || nClosedSide == 3) && ! bOptTwoOpposite) { // inverto il percorso @@ -2630,7 +2637,8 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c } // estendo la fine del percorso - if ( ! ( nClosedSide == 3 && bOptTwoOpposite)) + //if ( ! ( nClosedSide == 3 && bOptTwoOpposite)) + if (( nClosedSide == 2 && ! bOptTwoOpposite) || ( nClosedSide == 3 && ! bOptTwoOpposite)) pCrvCurr->ExtendEndByLen( max( m_TParams.m_dDiam / 4 - dOffsOpt, 0.0)) ; // aggiungo il tratto per l'entrata, verifico se attacco fuori dal grezzo @@ -2933,7 +2941,7 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC { // check parametri - if ( pSrfZigZag == nullptr) + if ( pSrfZigZag == nullptr || ! pSrfZigZag->IsValid()) return true ; // creo il vettore dei contorni @@ -3492,7 +3500,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl return false ; // recupero la curva ORIGINALE che delimita la svuotatura (questa curva non risente dell'offset fatto dalla superificie creata dopo) - PtrOwner pCrvForId( GetCurveComposite( pSrfPocket->GetLoop( 0, 0))) ; + /*PtrOwner pCrvForId( GetCurveComposite( pSrfPocket->GetLoop( 0, 0))) ; int nCrvId = pCrvForId->GetTempProp( 0) ; PtrOwner pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ; bool bSrfOriIsCut = false ; @@ -3501,16 +3509,21 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl if ( IsNull( pCrvPocket) || pCrvPocket->GetCurveCount() == 0) return true ; bSrfOriIsCut = true ; - } + }*/ + + // recupero la curva dal bordo della superficie + PtrOwner pCrvPocket( ConvertCurveToComposite( pSrfPocket->GetLoop( 0, 0))) ; + if ( IsNull( pCrvPocket)) + return false ; // porto la curva nel sistema di riferimento locale - pCrvPocket->ToLoc( frPocket) ; + //pCrvPocket->ToLoc( frPocket) ; m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvPocket->Clone()) ; // setto proprietà sulle curve - if ( ! bSrfOriIsCut) - SetCurveAllTempProp( nCrvId, GetForcedClosed(), pCrvPocket) ; + //if ( ! bSrfOriIsCut) + // SetCurveAllTempProp( nCrvId, GetForcedClosed(), pCrvPocket) ; pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // sistemo senso antiorario visto dalla direzione di estrusione @@ -3562,96 +3575,66 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl vtDir.GetAngleXY( X_AX, dAng) ; if ( nClosedSides == 0) dAng += m_Params.m_dSideAngle ; + pSrfPocket->ToGlob( frPocket) ; pCrvPocket->ToGlob( frPocket) ; Frame3d frameH( frPocket) ; Point3d ptCen = frPocket.Orig() ; Vector3d vtExtr = frPocket.VersZ() ; frPocket.Rotate( ptCen, vtExtr, -dAng) ; + pSrfPocket->ToLoc( frPocket) ; pCrvPocket->ToLoc( frPocket) ; - // vettore contenente le curve di primo Offset ottimizzate ( bordo esterno Optimized e isole ) - ICRVCOMPOPOVECTOR vFirstOffsets ; - vFirstOffsets.emplace_back( pCrvPocket->Clone()) ; // la curva esterna modificata - // parametri per Offset double dTRad = m_TParams.m_dDiam / 2 ; double dMyOffs = dTRad + GetOffsR() ; double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ; // Offsetto la superficie per ricavare informazioni su eventuali isole e sulle loro possibili unioni - PtrOwner pSrfPocketClone( CloneSurfFlatRegion( pSrfPocket)) ; - if ( IsNull( pSrfPocketClone)) - return false ; - if ( ! pSrfPocketClone->Offset( - dMyOffs - dExtra, ICurve::OFF_FILLET)) { // le isole interne vanno Offsettate - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - - // creo la superficie per svuotatura ZigZag PtrOwner pSfrZigZag( CreateSurfFlatRegion()) ; if ( IsNull( pSfrZigZag) || ! pSfrZigZag->AddExtLoop( *pCrvPocket)) return false ; - - // creo la superficie per le curve di bordo - PtrOwner pSfrForCrv( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrForCrv) || ! pSfrForCrv->AddExtLoop( *pCrvPocket)) + PtrOwner pSfrForCrv( CloneSurfFlatRegion( pSfrZigZag)) ; + if ( IsNull( pSfrForCrv)) return false ; - - // creo una superficie come somma delle isole - PtrOwner pSfrToTIsl( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrToTIsl)) - return false ; - - // prendo i loop interni dalla superficie originale ! - for ( int c = 0 ; c < pSrfPocket->GetChunkCount() ; ++ c) { // sempre 1... (?) - for ( int l = 1 ; l < pSrfPocket->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvIslLoop( ConvertCurveToComposite( pSrfPocket->GetLoop( c, l))) ; - if ( IsNull( pCrvIslLoop) || ! pCrvIslLoop->IsValid()) - return false ; - pCrvIslLoop->ToGlob( frameH) ; - pCrvIslLoop->ToLoc( frPocket) ; - - // creo la superficie dal bordo dell'isola - // ( NB. facendo l'offset di un'isola non è detto che ottengo una sola curva) - PtrOwner pSfrIslOff1( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrIslOff1) || ! pSfrIslOff1->AddExtLoop( *pCrvIslLoop)) - return false ; - - // per sottrarre devono essere coerenti - if ( AreOppositeVectorApprox( pSfrIslOff1->GetNormVersor(), pSfrZigZag->GetNormVersor())) - pSfrIslOff1->Invert() ; - PtrOwner pSfrIslOff2( CloneSurfFlatRegion( pSfrIslOff1)) ; - if ( IsNull( pSfrIslOff2)) - return false ; - - // Offset 1 ed Offset 2 - if ( ! pSfrIslOff1->Offset( dMyOffs + dExtra, ICurve::OFF_FILLET) || - ! pSfrIslOff2->Offset( dMyOffs, ICurve::OFF_FILLET)) - return false ; - - // aggiorno la regione totale delle isole - if ( ! pSfrToTIsl->IsValid() || pSfrToTIsl->GetChunkCount() == 0) - pSfrToTIsl.Set( pSfrIslOff1->Clone()) ; - else - pSfrToTIsl->Add( *pSfrIslOff1) ; - - // sottraggo - if ( ! pSfrZigZag->Subtract( *pSfrIslOff1) || ! pSfrForCrv->Subtract( *pSfrIslOff2)) { - if ( ! pSfrZigZag->Subtract( *pSfrIslOff1)) { - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZigZag->Clone()) ; - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrIslOff1->Clone()) ; - } - else { - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrForCrv->Clone()) ; - m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrIslOff2->Clone()) ; - } - return false ; - } + for ( int l = 1 ; l < pSrfPocket->GetLoopCount( 0) ; ++ l) { + PtrOwner pCrvLoopIsl( pSrfPocket->GetLoop( 0, l)) ; + if ( IsNull( pCrvLoopIsl)) + return false ; + // aggiungo alla pSrfForCurves ( così non considero il dExtra) + pSfrForCrv->AddIntLoop( *pCrvLoopIsl) ; + // effettuo l'offset di dExtra ( cos' considero il dExtra come distanza dal bordo delle isole) + pCrvLoopIsl->Invert() ; + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( pCrvLoopIsl, dExtra, ICurve::OFF_CHAMFER)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; } + PtrOwner pCrvBorderIsl( OffsCrv.GetLongerCurve()) ; + if ( ! pSfrZigZag->AddIntLoop( *pCrvBorderIsl)) + return false ; + } + + + + // Offset per i bordi e percorsi a ZigZag + if ( ! pSfrZigZag->Offset( - dMyOffs, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + if ( ! pSfrForCrv->Offset( - dMyOffs , ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + if ( ! pSfrForCrv->IsValid()) { + bOptimizedZigZag = false ; + return true ; } // calcolo il percorso di svuotatura + pSfrZigZag->ToGlob( frPocket) ; + m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZigZag->Clone()) ; + pSfrZigZag->ToLoc( frPocket) ; if ( ! CalcZigZag( pSfrZigZag, vpCrvs)) return false ; @@ -3660,15 +3643,55 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl double dAreaPrec, dAreaAft ; const ICurve* pCrvExtLoop = pSfrForCrv->GetLoop( 0, 0) ; Plane3d plH ; - if ( ! pCrvPocket->GetArea( plH, dAreaPrec) || + PtrOwner pSfrByCrvPocket( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrByCrvPocket) || ! pSfrByCrvPocket->AddExtLoop( *pCrvPocket)) + return false ; + if ( ! pSfrByCrvPocket->Offset( - dMyOffs, ICurve::OFF_CHAMFER)) + return false ; + if ( ! pSfrByCrvPocket->GetArea( dAreaPrec) || ! pCrvExtLoop->GetArea( plH, dAreaAft)) return false ; + // se l'area è cambiata... if ( abs( dAreaPrec - dAreaAft) > 5000 * EPS_SMALL) { ICURVEPOVECTOR vCrv ; ChainCurves ChainC ; + // creo una superficie come somma delle isole + PtrOwner pSfrToTIsl( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrToTIsl)) + return false ; + + // prendo i loop interni dalla superficie originale ! + for ( int c = 0 ; c < pSrfPocket->GetChunkCount() ; ++ c) { // sempre 1... (?) + for ( int l = 1 ; l < pSrfPocket->GetLoopCount( c) ; ++ l) { + PtrOwner pCrvIslLoop( ConvertCurveToComposite( pSrfPocket->GetLoop( c, l))) ; + if ( IsNull( pCrvIslLoop) || ! pCrvIslLoop->IsValid()) + return false ; + + // creo la superficie dal bordo dell'isola + // ( NB. facendo l'offset di un'isola non è detto che ottengo una sola curva) + PtrOwner pSfrIslOff1( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrIslOff1) || ! pSfrIslOff1->AddExtLoop( *pCrvIslLoop)) + return false ; + + // per sottrarre devono essere coerenti + if ( AreOppositeVectorApprox( pSfrIslOff1->GetNormVersor(), pSfrZigZag->GetNormVersor())) + pSfrIslOff1->Invert() ; + + // Offset 1 ed Offset 2 + if ( ! pSfrIslOff1->Offset( dMyOffs + 50 * EPS_SMALL, ICurve::OFF_FILLET)) + return false ; + + // aggiorno la regione totale delle isole + if ( ! pSfrToTIsl->IsValid() || pSfrToTIsl->GetChunkCount() == 0) + pSfrToTIsl.Set( pSfrIslOff1->Clone()) ; + else + pSfrToTIsl->Add( *pSfrIslOff1) ; + } + } + // il bordo esterno si è unito all'isola => devo percorrere la parte di bordo interna all'isola for ( int c = 0 ; c < pSfrForCrv->GetChunkCount() ; ++ c) { const ICurve* pCrvExt = pSfrForCrv->GetLoop( c, 0) ; @@ -3744,8 +3767,18 @@ Pocketing::ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOpt pCrvPocket->GetCurve( nMax)->GetStartDir( vtDir) ; // aggiorno pCrvPocket con eventuale offset per regioni residue - if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 0, {}, dOffs)) - return true ; + //if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 0, {}, dOffs)) + // return true ; + OffsetCurve CrvOffs ; + if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + pCrvPocket->Clear() ; + pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ; + + if ( ! pCrvPocket->IsValid()) + return false ; bOptimizedZigZag = true ; return true ; @@ -3753,8 +3786,8 @@ Pocketing::ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOpt //------------------------------------------------------------------ bool -Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClosedId, bool& bOptimizedZigZag, Vector3d& vtDir, - double& dOffs) +Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClosedId, bool& bOptimizedZigZag, + Vector3d& vtDir, double& dOffs) { // verifico che il lato chiuso sia una linea PtrOwner pCrv( CloneCurveLine( pCrvPocket->GetCurve( nClosedId))) ; @@ -3763,22 +3796,41 @@ Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClose // aggiorno pCrvPocket con eventuale offset per regioni residue pCrv->GetStartDir( vtDir) ; - if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, {nClosedId}, dOffs)) - return true ; - // setto il vettore estrusione per eseguire correttamente offset - Vector3d vtExtr ; - pCrvPocket->GetExtrusion( vtExtr) ; - pCrv->SetExtrusion( vtExtr) ; + //if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, {nClosedId}, dOffs)) + // return true ; - pCrv->SimpleOffset( -m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL) ; + // Offset + OffsetCurve CrvOffs ; + if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } pCrv->ExtendStartByLen( 300) ; pCrv->ExtendEndByLen( 300) ; - // sarà la prima curva del percorso - if ( ! CutCurveWithLine( pCrvPocket, pCrv)) + pCrvPocket->Clear() ; + pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ; + if ( ! pCrvPocket->IsValid() || ! CutCurveWithLine( pCrvPocket, pCrv)) return false ; + pCrvPocket->ChangeStartPoint( nClosedId) ; + + + + // setto il vettore estrusione per eseguire correttamente offset + // Vector3d vtExtr ; + // pCrvPocket->GetExtrusion( vtExtr) ; + // pCrv->SetExtrusion( vtExtr) ; + + // pCrv->SimpleOffset( -m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL) ; + // pCrv->ExtendStartByLen( 300) ; + // pCrv->ExtendEndByLen( 300) ; + + //// sarà la prima curva del percorso + // if ( ! CutCurveWithLine( pCrvPocket, pCrv)) + // return false ; + bOptimizedZigZag = true ; return true ; } @@ -3817,41 +3869,48 @@ Pocketing::ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INT } // setto il vettore estrusione per eseguire correttamente offset - Vector3d vtExtr ; - pCrvPocket->GetExtrusion( vtExtr) ; - pCrv1->SetExtrusion( vtExtr) ; - pCrv2->SetExtrusion( vtExtr) ; + //Vector3d vtExtr ; + //pCrvPocket->GetExtrusion( vtExtr) ; + //pCrv1->SetExtrusion( vtExtr) ; + //pCrv2->SetExtrusion( vtExtr) ; // determino la curva chiusa più lunga double dLen1 ; pCrv1->GetLength( dLen1) ; double dLen2 ; pCrv2->GetLength( dLen2) ; // se non opposti, verifico che almeno una delle due sia corta - if ( ! bOpposite && dLen1 > 1.5 * m_TParams.m_dDiam && dLen2 > 1.5 * m_TParams.m_dDiam) + if ( ! bOpposite && dLen1 > /*1.5 **/ m_TParams.m_dDiam && dLen2 > /*1.5 **/ m_TParams.m_dDiam) return true ; - // trovo la direzione principale della svuotatura - if ( dLen1 > dLen2) - pCrv1->GetStartDir( vtDir) ; - else - pCrv2->GetStartDir( vtDir) ; + // taglio per ultima la curva più lunga + if ( dLen1 > dLen2) { + swap( pCrv1, pCrv2) ; + swap( vtDir1, vtDir2) ; + } + vtDir = vtDir2 ; + + //if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, bOpposite ? 2 : 1, vnClosedIds, dOffs)) + // return true ; // aggiorno pCrvPocket con eventuale offset per regioni residue - if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, bOpposite ? 2 : 1, vnClosedIds, dOffs)) - return true ; + + + OffsetCurve CrvOffs ; + if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + pCrvPocket->Clear() ; + pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ; - double dMyOffs = m_TParams.m_dDiam / 2 + GetOffsR() - 10 * EPS_SMALL ; - pCrv1->SimpleOffset( -dMyOffs) ; pCrv1->ExtendStartByLen( 300) ; pCrv1->ExtendEndByLen( 300) ; - if ( ! CutCurveWithLine( pCrvPocket, pCrv1)) - return false ; - - // sarà la prima curva del percorso - pCrv2->SimpleOffset( -dMyOffs) ; pCrv2->ExtendStartByLen( 300) ; pCrv2->ExtendEndByLen( 300) ; - if ( ! CutCurveWithLine( pCrvPocket, pCrv2)) + + if ( ! pCrvPocket->IsValid() || + ! CutCurveWithLine( pCrvPocket, pCrv1) || + ! CutCurveWithLine( pCrvPocket, pCrv2)) return false ; bOptimizedZigZag = true ; @@ -3883,6 +3942,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I pCrv3->GetStartPoint( ptStart3) ; Point3d ptEnd3 ; pCrv3->GetEndPoint( ptEnd3) ; + if ( AreSamePointApprox( ptEnd1, ptStart2) && AreSamePointApprox( ptEnd2, ptStart3)) ; else if ( AreSamePointApprox( ptEnd2, ptStart3) && AreSamePointApprox( ptEnd3, ptStart1)) { @@ -3900,45 +3960,42 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I double dLen2 ; pCrv2->GetLength( dLen2) ; double dLen3 ; pCrv3->GetLength( dLen3) ; - if ( dLen2 > dLen1 && dLen2 > dLen3) { - if ( dLen1 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL || dLen3 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL) + if ( dLen2 > dLen1 && dLen2 > dLen3) { + if ( dLen1 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL || dLen3 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL) return true ; pCrv2->GetStartDir( vtDir) ; bOpposite = false ; } else { - if ( dLen2 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL) - return true ; - pCrv3->GetStartDir( vtDir) ; - bOpposite = true ; + return true ; + //if ( dLen2 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL) + // return true ; + //pCrv3->GetStartDir( vtDir) ; + //bOpposite = true ; } // aggiorno pCrvPocket con eventuale offset per regioni residue - if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, vnClosedIds, dOffs)) - return true ; + //if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, vnClosedIds, dOffs)) + // return true ; - // setto il vettore estrusione per eseguire correttamente offset - Vector3d vtExtr ; - pCrvPocket->GetExtrusion( vtExtr) ; - pCrv1->SetExtrusion( vtExtr) ; - pCrv2->SetExtrusion( vtExtr) ; - pCrv3->SetExtrusion( vtExtr) ; + OffsetCurve CrvOffs ; + if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + pCrvPocket->Clear() ; + pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ; - double dMyOffs = m_TParams.m_dDiam / 2 + GetOffsR() - 10 * EPS_SMALL ; - pCrv1->SimpleOffset( - dMyOffs) ; pCrv1->ExtendStartByLen( 300) ; pCrv1->ExtendEndByLen( 300) ; if ( ! CutCurveWithLine( pCrvPocket, pCrv1)) return false ; - pCrv3->SimpleOffset( -dMyOffs) ; pCrv3->ExtendStartByLen( 300) ; pCrv3->ExtendEndByLen( 300) ; if ( ! CutCurveWithLine( pCrvPocket, pCrv3)) return false ; - // sarà la prima curva del percorso - pCrv2->SimpleOffset( -dMyOffs) ; pCrv2->ExtendStartByLen( 300) ; pCrv2->ExtendEndByLen( 300) ; if ( ! CutCurveWithLine( pCrvPocket, pCrv2)) @@ -3953,7 +4010,7 @@ bool Pocketing::ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vector3d& vtMainDir, int nOffsettedEdgesOnY, const INTVECTOR& vnClosedIds, double& dOffs) { - // calcolo il side step che verr� utilizzato in CalcZigZag + // calcolo il side step che verrà utilizzato in CalcZigZag Frame3d frLoc ; if ( ! frLoc.Set( ORIG, Z_AX, vtMainDir)) return true ; @@ -3968,6 +4025,11 @@ Pocketing::ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vect dDimY -= nOffsettedEdgesOnY * ( 0.5 * m_TParams.m_dDiam + GetOffsR()) ; int nYStep = static_cast( ceil( ( dDimY - 30 * EPS_SMALL) / GetSideStep())) ; double dYSideStep = ( nYStep > 0 ? ( dDimY - 30 * EPS_SMALL) / nYStep : 0) ; + + dOffs = dYSideStep * 0.5 ; + return true ; + + // ---- check // individuo i lati vicini a quelli closed for ( int i = 0 ; i < ( int)vnClosedIds.size() ; i ++) { @@ -5445,16 +5507,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt if ( nReg == 0) { CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, pMCrv, pRCrv, bOptimizedTrap) ; if ( bOptimizedTrap) { - // ---- - pCrvTrap->ToGlob( frPocket) ; - if ( pCrvTrap->IsValid()) { - for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u) { - const ICurve* pCrv = pCrvTrap->GetCurve( u) ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ; - m_pGeomDB->SetMaterial( a, pCrv->GetTempProp( 0) == 0 ? BLUE : RED) ; - } - } - // ---- pMCrv->ToGlob( frPocket) ; pRCrv->ToGlob( frPocket) ; nReg = 1 ; @@ -5464,7 +5516,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt else return true ; } - return false ; } // porto la superficie nel frame della svuotatura @@ -5489,6 +5540,15 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ; return false ; } + if ( ! pSrfAct->IsValid()) { + // VRONOI ? + pSrfAct.Set( pSrfPrec->Clone()) ; + if ( ! pSrfAct->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) { + //int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ; + //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ; + return false ; + } + } // estraggo il contorno della FlatRegion (ciclo i Chunks e prendo i rispettivi Loops) if ( nIter == 0) { @@ -5499,7 +5559,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt pSrfAct.Set( pSrfChunknReg) ; } - int nChunks = pSrfAct->GetChunkCount(); + int nChunks = pSrfAct->GetChunkCount() ; for ( int i = 0 ; i < nChunks ; ++ i) { // per ogni chunk... @@ -7579,7 +7639,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr pCrvPocket->ToLoc( frTrap) ; // calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso) - double dLen0, dLen1, dLen2, dLen3 ; + double dLen0, dLen1, dLen2, dLen3, dMaxLarg = 0. ; pCrvPocket->GetCurve( nBase)->GetLength( dLen0) ; pCrvPocket->GetCurve( nSecondBase)->GetLength( dLen2) ; bool bRealTrap = pCrvPocket->GetCurveCount() == 4 ; @@ -7588,13 +7648,20 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr if ( bRealTrap) { pCrvPocket->GetCurve( nBase + 1)->GetLength( dLen1) ; pCrvPocket->GetCurve( nSecondBase + 1)->GetLength( dLen3) ; + // calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso) + Point3d ptOrig ; pCrvPocket->GetCurve( 1)->GetStartPoint( ptOrig) ; + Vector3d vtX ; pCrvPocket->GetCurve( 1)->GetStartDir( vtX) ; + Frame3d frDim ; frDim.Set( ptOrig, Z_AX, vtX) ; frDim.Invert() ; + BBox3d b3Dim ; pCrvPocket->GetBBox( frDim, b3Dim, BBF_EXACT) ; + dMaxLarg = ( vnProp[0] != 0 ? b3Dim.GetDimY() : dPocketSize) ; } + // calcolo percorso di svuotatura // se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale - if ( bRealTrap && - ( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL) || - vnProp[1] != 0 && vnProp[3] != 0 && vnProp[0] == 0 && vnProp[2] == 0 && max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL) { + if ( bRealTrap && dMaxLarg > m_TParams.m_dDiam + 10 * EPS_SMALL && + (( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL) || + vnProp[1] != 0 && vnProp[3] != 0 && vnProp[0] == 0 && vnProp[2] == 0 && max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL)) { if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, vnProp[0] == 0, pCrvPocket)) { pMCrv->Clear() ; return false ; @@ -7620,41 +7687,51 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr Point3d ptStart( dXCoordStart, dYCoord) ; Point3d ptEnd( dXCoordEnd, dYCoord) ; - //if ( AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && vnProp[0] != 0) { - // Vector3d vtDir1, vtDir3 ; - // pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ; - // pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ; - // // gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile - // if ( AreOppositeVectorApprox( vtDir1, vtDir3)) { - // PtrOwner pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ; - // PtrOwner pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ; - // if ( IsNull( pLine1) || IsNull( pLine3)) - // return true ; - // if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) || - // ! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR())) - // return true ; + if ( bRealTrap && AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && ( vnProp[0] != 0 || vnProp[2] != 0)) { + Vector3d vtDir1, vtDir3 ; + pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ; + pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ; + // gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile + if ( AreOppositeVectorApprox( vtDir1, vtDir3)) { + PtrOwner pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ; + PtrOwner pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ; + if ( IsNull( pLine1) || IsNull( pLine3)) + return false ; + if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) || + ! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR())) + return false ; - // Point3d ptS, ptE ; - // if ( vtDir3 * X_AX > EPS_SMALL) { - // pLine1->GetStartPoint( ptS) ; - // pLine3->GetStartPoint( ptE) ; - // } - // else { - // pLine1->GetEndPoint( ptE) ; - // pLine3->GetEndPoint( ptS) ; - // } + Point3d ptS, ptE ; + if ( vtDir3 * X_AX > EPS_SMALL) { + pLine1->GetStartPoint( ptS) ; + pLine3->GetStartPoint( ptE) ; + } + else { + pLine1->GetEndPoint( ptE) ; + pLine3->GetEndPoint( ptS) ; + } - // pMCrv->AddPoint( ptS) ; - // if ( vnProp[2] != 0) - // pMCrv->AddLine( ptE) ; - // else - // pMCrv->AddLine( ptStart) ; + if ( vnProp[0] != 0) { + pMCrv->AddPoint( ptS) ; + if ( vnProp[2] != 0) + pMCrv->AddLine( ptE) ; + else + pMCrv->AddLine( ptStart) ; + } + else { + pMCrv->AddPoint( ptE) ; + if ( vnProp[0] != 0) + pMCrv->AddLine( ptS) ; + else + pMCrv->AddLine( ptStart) ; + pMCrv->Invert() ; + } - // pMCrv->SetCurveTempProp( 0, 1) ; - // } - //} - //else { - if ( ! pMCrv->AddPoint( ptStart)) + pMCrv->SetCurveTempProp( 0, 1) ; + } + } + else { + if ( ! pMCrv->AddPoint( ptStart)) return true ; if ( ! pMCrv->AddLine( ptEnd)) return true ; @@ -7703,7 +7780,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr } - //} + } } if ( pMCrv->GetCurveCount() == 0) @@ -14905,6 +14982,14 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam } if ( ! CalcTrapezoidSpiralLocalFrame( pCrvTrap, vtDir, frTrap)) return false ; + bool bBaseOpen = false ; + bBaseOpen = ( pCrvTrap->GetCurve( 0)->GetTempProp( 0) == 1 || pCrvTrap->GetCurve( 2)->GetTempProp( 0) == 1 ) ; + // controllo dimensioni della svuotatura + if ( ! ( bBaseOpen && dPocketSize < dDiam + EPS_SMALL) && + abs( dPocketSize - dDiam) > EPS_SMALL) { + pCrvTrap->Clear() ; + return true ; + } // recupero flag aperto/chiuso dei lati if ( pCrvTrap->GetCurve( 1)->GetTempProp( 0) == 0 && pCrvTrap->GetCurve( 3)->GetTempProp( 0) == 0) { double dLen0, dLen2 ; @@ -14913,6 +14998,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL) pCrvTrap->Clear() ; } + // imposto le basi nBase = 0 ; nSecondBase = 2 ; @@ -15077,15 +15163,19 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam if ( ! CheckSecondBaseTrapezoid( pCrvCompo_c, i, nSecondBase)) return false ; if ( nSecondBase != -1) { - // se ho trovato la seconda base - if ( ! PreparareTrapezoidTwoBases( pCrvCompo_c, BBox, i, nSecondBase, bOk, pCrvTrap)) - return false ; - if ( bOk) { - // pCrvTrap contiene il trapezio - nBase = 0 ; - dPocketSize = BBox.GetDimY() ; - pCrvTrap->ToGlob( frTrap) ; - bBaseFound = true ; + // verifico che una delle due sia chiusa ( TO DO) + if ( pCrvCompo_c->GetCurve( nBase)->GetTempProp( 0) == 0 || + pCrvCompo_c->GetCurve( nSecondBase)->GetTempProp( 0) == 0) { + // se ho trovato la seconda base + if ( ! PreparareTrapezoidTwoBases( pCrvCompo_c, BBox, i, nSecondBase, bOk, pCrvTrap)) + return false ; + if ( bOk) { + // pCrvTrap contiene il trapezio + nBase = 0 ; + dPocketSize = BBox.GetDimY() ; + pCrvTrap->ToGlob( frTrap) ; + bBaseFound = true ; + } } } }