From 4e8953e8643bb057a32005b280010f27dbf8c855 Mon Sep 17 00:00:00 2001 From: DarioS Date: Mon, 23 Jan 2023 17:26:31 +0100 Subject: [PATCH] EgtMachKernel : - ritorno a stato pre svuotature con isole. --- Operation.cpp | 30 +- Operation.h | 1 - Pocketing.cpp | 5527 +++++++++++++------------------------------------ Pocketing.h | 77 +- 4 files changed, 1517 insertions(+), 4118 deletions(-) diff --git a/Operation.cpp b/Operation.cpp index f37bfad..8592032 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -637,38 +637,26 @@ Operation::GetMinDistanceFromRawSide( int nPhase, const Point3d& ptP, double dEx //---------------------------------------------------------------------------- bool -Operation::GetDistanceFromRawBottom(int nPhase, int nPathId, double dToler, double& dRbDist, double& dAllRbDist) const +Operation::GetDistanceFromRawBottom( int nPhase, int nPathId, double dToler, double& dRbDist, double& dAllRbDist) const { - if (m_pMchMgr == nullptr || m_pGeomDB == nullptr) - return false; - - // ricerco grezzi interessati dal percorso - BBox3d b3Compo; - if (!m_pGeomDB->GetGlobalBBox(nPathId, b3Compo)) - return false; - return GetDistanceFromRawBottom(nPhase, b3Compo, dToler, dRbDist, dAllRbDist); - -} - -//---------------------------------------------------------------------------- -bool -Operation::GetDistanceFromRawBottom(int nPhase, BBox3d& b3Test, double dToler, double& dRbDist, double& dAllRbDist) const -{ - if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) + if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // recupero distanza da fondo dei grezzi interessati o no dal percorso dRbDist = 0 ; dAllRbDist = 0 ; - b3Test.Expand(dToler, dToler, 0) ; + BBox3d b3Compo ; + if ( ! m_pGeomDB->GetGlobalBBox( nPathId, b3Compo)) + return false ; + b3Compo.Expand( dToler, dToler, 0) ; int nRawId = m_pMchMgr->GetFirstRawPart() ; while ( nRawId != GDB_ID_NULL) { // verifico che il grezzo compaia nella fase if ( m_pMchMgr->VerifyRawPartPhase( nRawId, nPhase)) { BBox3d b3Raw ; int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; - if (m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw)) { - double dDist = b3Test.GetMax().z - b3Raw.GetMin().z ; - if ( b3Test.OverlapsXY( b3Raw) && dDist > dRbDist) + if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw)) { + double dDist = b3Compo.GetMax().z - b3Raw.GetMin().z ; + if ( b3Compo.OverlapsXY( b3Raw) && dDist > dRbDist) dRbDist = dDist ; if ( dDist > dAllRbDist) dAllRbDist = dDist ; diff --git a/Operation.h b/Operation.h index 00f6678..7fd7d90 100644 --- a/Operation.h +++ b/Operation.h @@ -89,7 +89,6 @@ class Operation : public IUserObj { double dDummy ; return GetDistanceFromRawBottom( nPhase, nPathId, dToler, dRbDist, dDummy) ; } bool GetDistanceFromRawBottom( int nPhase, int nPathId, double dToler, double& dRbDist, double& dAllRbDist) const ; - bool GetDistanceFromRawBottom( int nPhase, BBox3d& b3Test, double dToler, double& dRbDist, double& dAllRbDist) const; bool GetRawGlobBox( int nPhase, int nPathId, double dToler, BBox3d& b3Raw) const ; bool GetRawGlobBox( int nPhase, const BBox3d& b3Test, double dToler, BBox3d& b3Raw) const ; diff --git a/Pocketing.cpp b/Pocketing.cpp index c09acd7..d1d14a0 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2017-2022 //---------------------------------------------------------------------------- // File : Pocketing.cpp Data : 24.08.22 Versione : 2.4h2 @@ -38,15 +38,6 @@ #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtNumUtils.h" -#include "/EgtDev/Include/EGkLinePntMinDistCurve.h" -#include "/EgtDev/Include/EGkDistPointCurve.h" -#include "/EgtDev/Include/EGkMedialAxis.h" -#include "/EgtDev/Include/EGkFilletChamfer.h" -#include "/EgtDev/Include/EGkCurveBezier.h" -#include "/EgtDev/Include/EGkGeoPoint3d.h" -#include "/EgtDev/Include/EGkIntersCurves.h" -#include "/EgtDev/Include/EGkLinePntTgCurve.h" -#include "/EgtDev/Include/EGkSfrCreate.h" #include using namespace std ; @@ -94,10 +85,7 @@ using namespace std ; //---------------------------------------------------------------------------- static string KEY_OPEN = "OPEN" ; static int LINK_CURVE_PROP = -3 ; -bool GetClosestOffsetToAPoint( ICRVCOMPOPOVECTOR& vCurves, Point3d& ptFocus, Point3d& ptCL, ICurveComposite* pCrv1, ICurveComposite* pCrv2, int& nIndex, bool bFirst = true) ; -bool GetClosestLinkToAPoint( ICURVEPOVECTOR& vCurves, ICRVCOMPOPOVECTOR& vOffs, Point3d& ptFocus, Point3d& ptCL, ICurveComposite* pCrv1, ICurveComposite* pCrv2, bool& bfound, int& nIndex) ; -bool RemoveFirstLoopFromSrfFlatRgn( ISurfFlatRegion* pSrfOrig, ISurfFlatRegion* pSrfRes) ; -bool RemoveSmallParts( ICURVEPOVECTOR& vCurve, double dToll) ; + //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), Pocketing) ; @@ -502,15 +490,15 @@ Pocketing::SetParam( int nType, const string& sVal) bool Pocketing::SetGeometry( const SELVECTOR& vIds) { - // verifico validità gestore DB geometrico + // verifico validità gestore DB geometrico if ( m_pGeomDB == nullptr) return false ; // reset della geometria corrente m_vId.clear() ; - // verifico che gli identificativi rappresentino delle entità ammissibili (tutte curve o tutte facce) + // verifico che gli identificativi rappresentino delle entità ammissibili (tutte curve o tutte facce) int nType = GEO_NONE ; for ( const auto& Id : vIds) { - // test sull'entità + // test sull'entità int nSubs ; if ( ! VerifyGeometry( Id, nSubs, nType)) { string sInfo = "Warning in Pocketing : Skipped entity " + ToString( Id) ; @@ -533,14 +521,14 @@ Pocketing::Preview( bool bRecalc) // reset numero percorsi di svuotatura generati m_nPockets = 0 ; - // verifico validità gestore DB geometrico e Id del gruppo + // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) return false ; // recupero gruppo per geometria ausiliaria int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; bool bChain = false ; - // se non c'è, lo aggiungo + // se non c'è, lo aggiungo if ( nAuxId == GDB_ID_NULL) { nAuxId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nAuxId == GDB_ID_NULL) @@ -583,7 +571,7 @@ Pocketing::Preview( bool bRecalc) // recupero gruppo per geometria di Preview int nPvId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_PV) ; - // se non c'è, lo aggiungo + // se non c'è, lo aggiungo if ( nPvId == GDB_ID_NULL) { nPvId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nPvId == GDB_ID_NULL) @@ -616,7 +604,7 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) // reset raggio massimo attacco ad elica nel caso di cerchi m_dMaxHelixRad = INFINITO ; - // verifico validità gestore DB geometrico e Id del gruppo + // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) return false ; @@ -628,8 +616,8 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) } // verifico se necessario continuare nell'aggiornamento - if ( !bRecalc && !bToolChanged && - ( m_nStatus == MCH_ST_OK || ( !bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) { + if ( ! bRecalc && ! bToolChanged && + ( m_nStatus == MCH_ST_OK || ( ! bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) { // confermo i percorsi di lavorazione m_nPockets = nCurrPockets ; LOG_DBG_INFO( GetEMkLogger(), "Pocketing apply skipped : status already ok") ; @@ -645,7 +633,7 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) // recupero gruppo per geometria ausiliaria int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; bool bChain = false ; - // se non c'è, lo aggiungo + // se non c'è, lo aggiungo if ( nAuxId == GDB_ID_NULL) { nAuxId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nAuxId == GDB_ID_NULL) @@ -682,7 +670,7 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) // recupero gruppo per geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; - // se non c'è, lo aggiungo + // se non c'è, lo aggiungo if ( nClId == GDB_ID_NULL) { nClId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nClId == GDB_ID_NULL) @@ -696,11 +684,11 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) // lavoro ogni singola catena bool bOk = true ; int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; - //while ( nPathId != GDB_ID_NULL) { - if ( ! ProcessPath( nAuxId, GDB_ID_NULL, nClId)) //nPathId - bOk = false ; - // nPathId = m_pGeomDB->GetNextGroup( nPathId) ; - //} + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) + bOk = false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } if ( ! bOk) return false ; @@ -725,7 +713,7 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) bool Pocketing::Update( bool bPostApply) { - // verifico validità gestore DB geometrico e Id del gruppo + // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) return false ; @@ -959,7 +947,7 @@ Pocketing::UpdateToolData( bool* pbChanged) bool Pocketing::GetGeometry( SELVECTOR& vIds) const { - // restituisco l'elenco delle entità + // restituisco l'elenco delle entità vIds = m_vId ; return true ; } @@ -972,7 +960,7 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; if ( pGObj == nullptr) return false ; - // se ammesse curve ed è tale + // se ammesse curve ed è tale if ( ( nType == GEO_NONE || nType == GEO_CURVE) && ( pGObj->GetType() & GEO_CURVE) != 0) { nType = GEO_CURVE ; const ICurve* pCurve = nullptr ; @@ -996,7 +984,7 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) } return true ; } - // se altrimenti ammessi testi ed è tale + // se altrimenti ammessi testi ed è tale else if ( ( nType == GEO_NONE || nType == EXT_TEXT) && pGObj->GetType() == EXT_TEXT) { nType = EXT_TEXT ; const IExtText* pText = ::GetExtText( pGObj) ; @@ -1005,7 +993,7 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) nSubs = 0 ; return true ; } - // se altrimenti ammesse superfici trimesh ed è tale + // se altrimenti ammesse superfici trimesh ed è tale else if ( ( nType == GEO_NONE || nType == SRF_TRIMESH) && pGObj->GetType() == SRF_TRIMESH) { nType = SRF_TRIMESH ; const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; @@ -1027,7 +1015,7 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) } return true ; } - // se altrimenti ammesse regioni ed è tale + // se altrimenti ammesse regioni ed è tale else if ( ( nType == GEO_NONE || nType == SRF_FLATRGN) && pGObj->GetType() == SRF_FLATRGN) { nType = SRF_FLATRGN ; const ISurfFlatRegion* pReg = ::GetSurfFlatRegion( pGObj) ; @@ -1094,7 +1082,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) return false ; // la duplico pCurve.Set( pOriCurve->Clone()) ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCurve) ; // recupero estrusione e spessore Vector3d vtExtr ; @@ -1122,7 +1110,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) // recupero l'outline del testo if ( ! pText->GetOutline( lstPC)) return false ; - // reset proprietà temporanee + // reset proprietà temporanee for ( auto pCrv : lstPC) ResetCurveAllTempProp( pCrv) ; // porto le curve in globale @@ -1144,72 +1132,21 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) pSurf->GetFacetLoops( nFacet, vPL) ; if ( vPL.empty()) return false ; - // recupero la normale esterna della faccia - Vector3d vtN ; - if ( ! pSurf->GetFacetNormal( nFacet, vtN)) - return false ; - // creo la curva a partire dei loop - for ( int i = 0 ; i < vPL.size() ; i++) { - PtrOwner pCrvCompo( CreateCurveComposite()) ; - pCrvCompo->FromPolyLine( vPL[i]) ; - if ( ! pCrvCompo->IsValid()) - return false ; - // reset delle proprietà temporanee - ResetCurveAllTempProp( pCrvCompo) ; - // determino eventuali lati aperti e aggiorno proprietà del contorno - int nInd = 0 ; - double dPar ; - bool bFound = vPL[i].GetFirstU( dPar, true) ; - while ( bFound) { - // recupero il flag - int nFlag = int( dPar) ; - // se non c'è nulla di adiacente, lato aperto - if (nFlag == SVT_NULL) - pCrvCompo->SetCurveTempProp( nInd, 1) ; - // altrimenti verifico se la faccia adiacente forma diedro convesso o concavo - else { - bool bAdjac ; - Point3d ptP1, ptP2 ; - double dAng ; - if ( ! pSurf->GetFacetsContact( nFacet, nFlag, bAdjac, ptP1, ptP2, dAng)) - dAng = - ANG_RIGHT ; - if ( dAng > - EPS_ANG_SMALL) - pCrvCompo->SetCurveTempProp( nInd, 1) ; - } - // passo al successivo - ++nInd ; - bFound = vPL[i].GetNextU( dPar, true) ; - } - // assegno l'estrusione dalla normale alla faccia - pCrvCompo->SetExtrusion( vtN) ; - // unisco le eventuali parti allineate - pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - // la porto in globale - pCrvCompo->ToGlob( frGlob) ; - // sistemazioni varie - AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, 0) ; - // la restituisco - lstPC.emplace_back( Release( pCrvCompo)) ; - } - - return true ; - - /* // creo la curva a partire da quello esterno PtrOwner pCrvCompo( CreateCurveComposite()) ; pCrvCompo->FromPolyLine( vPL[0]) ; if ( ! pCrvCompo->IsValid()) return false ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCrvCompo) ; - // determino eventuali lati aperti e aggiorno proprietà del contorno + // determino eventuali lati aperti e aggiorno proprietà del contorno int nInd = 0 ; double dPar ; bool bFound = vPL[0].GetFirstU( dPar, true) ; while ( bFound) { // recupero il flag int nFlag = int( dPar) ; - // se non c'è nulla di adiacente, lato aperto + // se non c'è nulla di adiacente, lato aperto if ( nFlag == SVT_NULL) pCrvCompo->SetCurveTempProp( nInd, 1) ; // altrimenti verifico se la faccia adiacente forma diedro convesso o concavo @@ -1241,7 +1178,6 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) // la restituisco lstPC.emplace_back( Release( pCrvCompo)) ; return true ; - */ } // se altrimenti regione else if ( pGObj->GetType() == SRF_FLATRGN) { @@ -1265,9 +1201,9 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) // recupero i contorni del chunk for ( int nL = 0 ; nL < pReg->GetLoopCount( nC) ; ++ nL) { PtrOwner pCrvCompo( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo) || ! pCrvCompo->AddCurve( pReg->GetLoop( nC, nL))) + if ( IsNull( pCrvCompo) || ! pCrvCompo->AddCurve( pReg->GetLoop( nC, nL))) return false ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCrvCompo) ; // assegno l'estrusione dalla normale alla regione pCrvCompo->SetExtrusion( vtN) ; @@ -1294,7 +1230,7 @@ Pocketing::SetCurveAllTempProp( int nCrvId, ICurve* pCurve) { if ( pCurve == nullptr) return false ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCurve) ; // verifico se presenti info per lati aperti if ( ! m_pGeomDB->ExistsInfo( nCrvId, KEY_OPEN)) @@ -1333,11 +1269,11 @@ Pocketing::ResetCurveAllTempProp( ICurve* pCurve) //---------------------------------------------------------------------------- bool -Pocketing::Chain( int nGrpDestId) //AUX +Pocketing::Chain( int nGrpDestId) { // vettore puntatori alle curve ICURVEPOVECTOR vpCrvs ; - vpCrvs.reserve( m_vId.size()) ; // OGGETTI CLICCATI PRIMA DELL'APPLY + vpCrvs.reserve( m_vId.size()) ; // vettore selettori delle curve originali SELVECTOR vInds ; // recupero tutte le curve e le porto in globale @@ -1381,9 +1317,7 @@ Pocketing::Chain( int nGrpDestId) //AUX // recupero i percorsi concatenati int nCount = 0 ; INTVECTOR vnId2 ; - while ( chainC.GetChainFromNear( ptNear, false, vnId2)) { - // creo una curva composita PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo)) @@ -1436,33 +1370,29 @@ Pocketing::Chain( int nGrpDestId) //AUX } // creo nuovo gruppo int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ; - if ( nPathId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( ++ nCount)) ; m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( vId2)) ; // inserisco la curva composita nel gruppo destinazione int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::Release( pCrvCompo)) ; - if ( nNewId == GDB_ID_NULL) return false ; // salvo info con eventuali lati aperti if ( ! vOpen.empty()) m_pGeomDB->SetInfo( nNewId, KEY_OPEN, vOpen) ; } - return true ; } //---------------------------------------------------------------------------- bool -Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) +Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) { - // ========= GRUPPO TMP =================== - // recupero gruppo per geometria temporanea ( Gruppo TMP ) + // recupero gruppo per geometria temporanea const string GRP_TEMP = "Temp" ; int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; - // se non c'è, lo aggiungo + // se non c'è, lo aggiungo if ( nTempId == GDB_ID_NULL) { nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nTempId == GDB_ID_NULL) @@ -1475,247 +1405,119 @@ Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) // in ogni caso lo dichiaro temporaneo e non visibile m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; - // ======================================= - // ========= STEP ======================== - // verifico che lo step dell'utensile sia sensato - double dOkStep = ( m_Params.m_dStep > EPS_SMALL ? m_Params.m_dStep + EPS_SMALL : 0); - const double MIN_ZSTEP = 1.0 ; - if ( dOkStep >= EPS_SMALL && dOkStep < MIN_ZSTEP) { - dOkStep = MIN_ZSTEP + EPS_SMALL ; - string sInfo = "Warning in Pocketing : machining step too small (" + - ToString(m_Params.m_dStep, 2) + ")" ; - m_pMchMgr->SetWarning( 2456, sInfo) ; - } - - // verifico di non superare il massimo materiale - if ( m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL) { - dOkStep = m_TParams.m_dMaxMat + EPS_SMALL ; - string sInfo = "Warning in Pocketing : machining step (" + ToString(m_Params.m_dStep, 1) + - ") bigger than MaxMaterial (" + ToString(m_TParams.m_dMaxMat, 1) + ")" ; - m_pMchMgr->SetWarning( 2457, sInfo) ; - } - // ======================================= - - // recupero eventuale flag di lato aperto forzato fuori dal grezzo - int nOpenOutRaw ; - m_bOpenOutRaw = ( FromString( ExtractInfo(m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ; - - SurfFlatRegionByContours SrfByC ; // superificie totale generata da tutte le curve concatenate - Plane3d plAux ; bool bFirstPlane = true ; // piano Ausiliario per verificare che le curve siano complanari - Vector3d vtExtr ; - double dThick = -INFINITO ; // spessore più grande tra le curve - int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; - - while ( nPathId != GDB_ID_NULL) { // Scorro tutte le curve concatenate per creare la superficie da lavorare - - int nPi = m_pGeomDB->GetFirstInGroup( nPathId) ; - const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( nPi) ; - if ( pGObj == nullptr) - return false ; - const ICurve* pOriCurve = ::GetCurve( pGObj) ; - if ( pOriCurve == nullptr) - return false ; - PtrOwner pCompoOriCrv( GetCurveComposite( pOriCurve->Clone())) ; - if ( IsNull( pCompoOriCrv)) - return false ; - - // unisco le parti allineate (tranne inizio-fine se chiusa) - if ( ! pCompoOriCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false, true)) - return false ; - - // controllo se trovo dei Flag per lati aperti - bool bSomeOpen = m_pGeomDB->ExistsInfo( nPi, KEY_OPEN) ; - if ( bSomeOpen) { - int nOpen ; - if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "Open="), nOpen) && nOpen == 0) - bSomeOpen = false ; - } - - // annullo i flag di tratto aperto - for ( int i = 0; i < int( pCompoOriCrv->GetCurveCount()) ; ++i) - pCompoOriCrv->SetCurveTempProp( i, 0, 0) ; // alla sottocurva - - // aggiorno flag per lati aperti - if ( bSomeOpen) { - INTVECTOR vOpen ; - m_pGeomDB->GetInfo( nPi, KEY_OPEN, vOpen) ; - for (int j : vOpen) - pCompoOriCrv->SetCurveTempProp( j, 1, 0) ; // alla sottocurva - } - - // recupero estrusione e spessore - Vector3d vtExtr_p = Z_AX ; - pCompoOriCrv->GetExtrusion( vtExtr_p) ; - double dThick_p ; - pCompoOriCrv->GetThickness( dThick_p) ; - - // verifico sia piana e se necessario la appiattisco - PtrOwner pFlatCrv( FlattenCurve( *pCompoOriCrv, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ; - if ( IsNull( pFlatCrv)) { - Plane3d plPlane ; - if ( ! pCompoOriCrv->IsFlat( plPlane, true, 50 * EPS_SMALL)) - m_pMchMgr->SetLastError( 2403, "Error in Pocketing : Contour Not Flat") ; - else - m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ; - return false; - } - pFlatCrv->GetExtrusion( vtExtr_p) ; - pCompoOriCrv->Clear() ; - pCompoOriCrv->AddCurve( Release( pFlatCrv)) ; - pCompoOriCrv->SetExtrusion( vtExtr_p) ; - pCompoOriCrv->SetThickness( dThick_p) ; - - // setto come proprietà temperanea il suo Id ( per riprenderlo dopo per casi ottimizzati) - pCompoOriCrv->SetTempProp( nPi, 0) ; // a tutta la curva - - // controllo che le curve siano complanari e con stessa estrusione (la prima come riferimento) - Plane3d plAct ; - pCompoOriCrv->IsFlat( plAct) ; - if ( bFirstPlane) { - plAux = plAct ; - bFirstPlane = false ; - pCompoOriCrv->GetThickness( dThick_p) ; - dThick = dThick_p ; // prima come riferimento - vtExtr = vtExtr_p ; // prima come riferimento - SrfByC.AddCurve( pCompoOriCrv->Clone()) ; - } - else { - Vector3d vtN1, vtN2 ; - if ( abs( plAct.GetDist() - plAux.GetDist()) < EPS_SMALL - && AreSameOrOppositeVectorApprox( plAct.GetVersN(), plAux.GetVersN()) // se stessa normale - && AreSameVectorApprox( vtExtr, vtExtr_p)) { // se stessa estrusione - SrfByC.AddCurve( pCompoOriCrv->Clone()) ; - // prendo Thickness Massima tra tutte le curve dei chunks - double dCurrThink ; - pCompoOriCrv->GetThickness( dCurrThink) ; - if ( dCurrThink > dThick) - dThick = dCurrThink ; - } - } - - nPathId = m_pGeomDB->GetNextGroup( nPathId) ; // aggiorno il PathId con il successivo nel gruppo - - } - - // creazione della superficie da lavorare completa (dall'unione di tutte le curve concatenate) - PtrOwner pSrfByC( SrfByC.GetSurf()) ; - if ( pSrfByC == nullptr) + // verifico sia una curva chiusa (deve delimitare l'area da svuotare) + int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; + if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) return false ; - - // creo la superificie finale ( quella con le curve modificate se contengono dei lati aperti ) - PtrOwner pSrfPock( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfPock)) + ICurve* pCrv = ::GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; + if ( pCrv == nullptr || ! pCrv->IsClosed()) { + m_pMchMgr->SetLastError( 2402, "Error in Pocketing : Open Contour") ; return false ; - - // vettore per i punti iniziali delle curve che definiscono i contorni dei Chunks - PNTVECTOR vPtStart( pSrfByC->GetChunkCount()) ; - - // vettori controllo per lati aperti - BOOLVECTOR vbMidOpen( pSrfByC->GetChunkCount()) ; - PNTVECTOR vPtMidOpen( vbMidOpen.size()) ; - VCT3DVECTOR vVtMidOut( vPtMidOpen.size()) ; - - for ( int c = 0 ; c < pSrfByC->GetChunkCount() ; c++) { // ciclo sui chunk ottenuti - - // riferimento della curva esterna del chunk (c)-esimo (bordo esterno) - PtrOwner pCrvExt( GetCurveComposite( pSrfByC->GetLoop( c, 0))) ; - bool bSomeOpen = m_pGeomDB->ExistsInfo( pCrvExt->GetTempProp( 0), KEY_OPEN) ; - - // se trovo dei ==| LATI APERTI |== allora modifico il bordo esterno - bool bMidOpen = false ; - Point3d ptMidOpen ; - Vector3d vtMidOut ; - if ( bSomeOpen) { - // ricerca del punto medio del lato aperto più lungo - bMidOpen = GetMidOfLongestOpenSide( pCrvExt, ptMidOpen, vtMidOut) ; - // sistemazioni per eventuali lati aperti - if ( ! AdjustContourWithOpenEdges( pCrvExt)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false; - } - } - - // sposto l'inizio a metà del tratto più lungo ( o aperto più lungo) della curva esterna - if ( bMidOpen) { - const double LEN_OUT = 5 ; - double dPar ; int nFlag ; - bMidOpen = ( DistPointCurve( ptMidOpen + LEN_OUT * vtMidOut, *pCrvExt).GetParamAtMinDistPoint( 0, dPar, nFlag) && pCrvExt->ChangeStartPoint( dPar)) ; - } - if ( ! bMidOpen) - AdjustContourStart( pCrvExt) ; - - // recupero il punto di inizio (per poi salvarlo nelle info di CL path) - Point3d ptStart ; pCrvExt->GetStartPoint( ptStart) ; - vPtStart[c] = ptStart ; // salvataggio del punto nel vettore - - // inserisco il Loop esterno - if ( ! pSrfPock->AddExtLoop( pCrvExt->Clone())) - return false ; - - // aggiorno i vettori di controllo - vbMidOpen.push_back( bMidOpen) ; - vPtMidOpen.push_back( ptMidOpen) ; - vVtMidOut.push_back( vtMidOut) ; - - for ( int l = 1 ; l < pSrfByC->GetLoopCount( c) ; l++) { // scorro il loop interni del Chunk ( bordi delle isole ) - - PtrOwner pCrvInt(( ICurveComposite*)pSrfByC->GetLoop( c, l)) ; - if ( IsNull( pCrvInt)) - return false ; - - bool bSomeOpen_i = m_pGeomDB->ExistsInfo( pCrvInt->GetTempProp( 0), KEY_OPEN) ; - - // se trovo dei ==| LATI APERTI |== allora modifico il bordo esterno - bool bMidOpen_i = false ; - Point3d ptMidOpen_i ; - Vector3d vtMidOut_i ; - if ( bSomeOpen_i) { - // ricerca del punto medio del lato aperto più lungo - bMidOpen_i = GetMidOfLongestOpenSide( pCrvInt, ptMidOpen_i, vtMidOut_i) ; - // sistemazioni per eventuali lati aperti - if ( ! AdjustContourWithOpenEdges( pCrvInt)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false; - } - } - if ( bMidOpen_i) { - const double LEN_OUT = 5 ; - double dPar_i; int nFlag_i ; - bMidOpen_i = ( DistPointCurve( ptMidOpen_i + LEN_OUT * vtMidOut_i, *pCrvInt).GetParamAtMinDistPoint( 0, dPar_i, nFlag_i) && pCrvInt->ChangeStartPoint( dPar_i)) ; - } - if ( ! bMidOpen_i) - AdjustContourStart( pCrvInt) ; - - // aggiungo curve interne - if ( ! pSrfPock->AddIntLoop( pCrvInt->Clone())) - return false ; - } } - // normale della superifice finale || extrusione prima curva selezionata - if ( AreOppositeVectorApprox( vtExtr, pSrfPock->GetNormVersor())) - pSrfPock->Invert() ; + // copio la curva composita da elaborare + int nCopyId = m_pGeomDB->CopyGlob( nCrvId, GDB_ID_NULL, nTempId) ; + if ( nCopyId == GDB_ID_NULL) + return false ; + ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ; + + // annullo i flag di tratto aperto + for ( int i = 0 ; i < int( pCompo->GetCurveCount()) ; ++ i) + pCompo->SetCurveTempProp( i, 0) ; + + // verifico se vanno gestiti i lati aperti + bool bSomeOpen = m_pGeomDB->ExistsInfo( nCrvId, KEY_OPEN) ; + if ( bSomeOpen) { + int nOpen ; + if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "Open="), nOpen) && nOpen == 0) + bSomeOpen = false ; + } + + // aggiorno flag per lati aperti + if ( bSomeOpen) { + INTVECTOR vOpen ; + m_pGeomDB->GetInfo( nCrvId, KEY_OPEN, vOpen) ; + for ( int j : vOpen) + pCompo->SetCurveTempProp( j, 1) ; + } + + // recupero estrusione e spessore + Vector3d vtExtr = Z_AX ; + pCompo->GetExtrusion( vtExtr) ; + double dThick ; + pCompo->GetThickness( dThick) ; - if ( m_Params.m_bToolInvert) { // eventuale inversione direzione utensile - vtExtr.Invert() ; - pSrfPock->Invert() ; - dThick = -dThick ; + if ( m_Params.m_bToolInvert) { + vtExtr.Invert() ; + pCompo->SetExtrusion( vtExtr) ; + dThick = - dThick ; + pCompo->SetThickness( dThick) ; } + // verifico sia piana e se necessario la appiattisco + PtrOwner pFlatCrv( FlattenCurve( *pCompo, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ; + if ( IsNull( pFlatCrv)) { + Plane3d plPlane ; + if ( ! pCompo->IsFlat( plPlane, true, 50 * EPS_SMALL)) + m_pMchMgr->SetLastError( 2403, "Error in Pocketing : Contour Not Flat") ; + else + m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ; + return false ; + } + pFlatCrv->GetExtrusion( vtExtr) ; + pCompo->Clear() ; + pCompo->AddCurve( Release( pFlatCrv)) ; + pCompo->SetExtrusion( vtExtr) ; + pCompo->SetThickness( dThick) ; + // sistemo senso antiorario visto dalla direzione di estrusione + Plane3d plPlane ; double dArea ; + pCompo->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) + pCompo->Invert() ; + + // unisco le parti allineate (tranne inizio-fine se chiusa) + if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false, true)) + return false ; + + // se ci sono lati aperti + bool bMidOpen = false ; + Point3d ptMidOpen ; + Vector3d vtMidOut ; + if ( bSomeOpen) { + // ricerca del punto medio del lato aperto più lungo + bMidOpen = GetMidOfLongestOpenSide( pCompo, ptMidOpen, vtMidOut) ; + // sistemazioni per eventuali lati aperti + if ( ! AdjustContourWithOpenEdges( pCompo)) { + m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; + return false ; + } + } + + // sposto l'inizio a metà del tratto più lungo ( o aperto più lungo) + if ( bMidOpen) { + const double LEN_OUT = 5 ; + double dPar ; int nFlag ; + bMidOpen = ( DistPointCurve( ptMidOpen + LEN_OUT * vtMidOut, *pCompo).GetParamAtMinDistPoint( 0, dPar, nFlag) && pCompo->ChangeStartPoint( dPar)) ; + } + if ( ! bMidOpen) + AdjustContourStart( pCompo) ; + + // recupero il punto di inizio (per poi salvarlo nelle info di CL path) + Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; + // recupero il box del grezzo in globale BBox3d b3Raw ; - BBox3d b3Chunk ; pSrfPock->GetBBox( GLOB_FRM, b3Chunk) ; - if ( ! GetRawGlobBox( m_nPhase, b3Chunk, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { + if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { m_pMchMgr->SetLastError( 2405, "Error in Pocketing : Empty RawBox") ; return false ; } // recupero distanza da fondo dei grezzi interessati dal percorso - double dRbDist = 0 ; double dAllRbDist = 0 ; + double dRbDist = 0 ; if ( AreSameVectorApprox( vtExtr, Z_AX)) { - if ( ! GetDistanceFromRawBottom( m_nPhase, b3Chunk, m_TParams.m_dTDiam, dRbDist, dAllRbDist)) + if ( ! GetDistanceFromRawBottom( m_nPhase, nCopyId, m_TParams.m_dTDiam, dRbDist)) return false ; } @@ -1734,62 +1536,76 @@ Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) // sottraggo eventuale offset longitudinale dDepth -= GetOffsL() ; + // recupero nome del path + string sPathName ; + m_pGeomDB->GetName( nPathId, sPathName) ; + // assegno il versore fresa Vector3d vtTool = vtExtr ; - m_bAggrBottom = false; - // calcolo l'elevazione massima - double dElev = -INFINITO ; - for ( int c = 0; c < pSrfPock->GetChunkCount() ; c++) { - double dCurrElev ; - if ( CalcRegionElevation( GetCurveComposite( pSrfPock->GetLoop( c,0)), vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dCurrElev)) { - if ( dCurrElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { - BBox3d b3Crv ; - pSrfPock->GetLoop( c, 0)->GetLocalBBox( b3Crv) ; - dCurrElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min(0., dThick) + dDepth) ; - } - if ( dCurrElev > dElev) - dElev = dCurrElev ; + double dElev ; + if ( CalcRegionElevation( pCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dElev)) { + if ( dElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { + BBox3d b3Crv ; + pCompo->GetLocalBBox( b3Crv) ; + dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min( 0., dThick) + dDepth) ; } - else - return false; } - + else + return false ; // eventuale imposizione massima elevazione da note utente double dMaxElev ; - if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) + if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) dElev = dMaxElev ; + // verifico che lo step dell'utensile sia sensato + double dOkStep = ( m_Params.m_dStep > EPS_SMALL ? m_Params.m_dStep + EPS_SMALL : 0) ; + const double MIN_ZSTEP = 1.0 ; + if ( dOkStep >= EPS_SMALL && dOkStep < MIN_ZSTEP) { + dOkStep = MIN_ZSTEP + EPS_SMALL ; + string sInfo = "Warning in Pocketing : machining step too small (" + + ToString( m_Params.m_dStep, 2) + ")" ; + m_pMchMgr->SetWarning( 2456, sInfo) ; + } + // verifico che il massimo materiale dell'utensile sia sensato const double MIN_MAXMAT = 1.0 ; if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) { string sInfo = "Error in Pocketing : Tool MaxMaterial too small (" + - ToString(m_TParams.m_dMaxMat, 2) + ")" ; - m_pMchMgr->SetLastError(2422, sInfo) ; + ToString( m_TParams.m_dMaxMat, 2) + ")" ; + m_pMchMgr->SetLastError( 2422, sInfo) ; return false ; } + // verifico di non superare il massimo materiale + // se lo step supera la capacità dell'utensile + if ( m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL) { + dOkStep = m_TParams.m_dMaxMat + EPS_SMALL ; + string sInfo = "Warning in Pocketing : machining step (" + ToString( m_Params.m_dStep, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + m_pMchMgr->SetWarning( 2457, sInfo) ; + } // se lavorazione singola - if ( dOkStep < EPS_SMALL || dOkStep > dElev) { - // se l'elevazione supera la capacità dell'utensile - if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL ) { - string sInfo = "Warning in Pocketing : machining depth (" + ToString(dElev, 1) + - ") bigger than MaxMaterial (" + ToString(m_TParams.m_dMaxMat, 1) + ")" ; - m_pMchMgr->SetWarning(2458, sInfo) ; + if ( dOkStep < EPS_SMALL || dOkStep > dElev) { + // se l'elevazione supera la capacità dell'utensile + if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL) { + string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + m_pMchMgr->SetWarning( 2458, sInfo) ; dDepth -= dElev - m_TParams.m_dMaxMat ; dElev = m_TParams.m_dMaxMat ; } } - // altrimenti lavorazione a step + // altrimenti lavorazione a step else { - // se l'elevazione supera il massimo affondamento dell'utensile + // se l'elevazione supera il massimo affondamento dell'utensile double dSafe = m_pMchMgr->GetCurrMachiningsMgr()->GetMaxDepthSafe() ; double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? m_dTHoldBase : m_dTHoldLen) - dSafe ; if ( dElev > dMaxDepth + EPS_SMALL) { - // segnalo, riduco e continuo + // segnalo, riduco e continuo string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + - ") bigger than MaxDepth (" + ToString(dMaxDepth, 1) + ")" ; + ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; m_pMchMgr->SetWarning( 2458, sInfo) ; dDepth -= dElev - dMaxDepth ; dElev = dMaxDepth ; @@ -1798,18 +1614,20 @@ Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) // verifico se tavola basculante bool bTiltTab = false ; - m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ; + m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ; // verifico se testa da sopra (Z+) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; // verifiche per svuotature dal basso - m_bAggrBottom = false ; - if ( ! VerifyPathFromBottom( pSrfPock, vtTool)) { - return false; + m_bAggrBottom = false ; + if ( ! VerifyPathFromBottom( pCompo, vtTool)) { + return false ; } - string sPathName = "P1" ; + // recupero eventuale flag di lato aperto forzato fuori dal grezzo + int nOpenOutRaw ; + m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ; // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { @@ -1820,7 +1638,7 @@ Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) m_pGeomDB->SetName( nPxId, sPathName) ; m_pGeomDB->SetMaterial( nPxId, GREEN) ; // creo l'anteprima del percorso - if ( ! GeneratePocketingPv( nPxId, pSrfPock)) + if ( ! GeneratePocketingPv( nPxId, pCompo)) return false ; } @@ -1835,47 +1653,47 @@ Pocketing::ProcessPath(int nAuxId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta int nSplitArcs = m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() ; - bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || - ( nSplitArcs == SPLAR_NO_XY_PLANE && !vtExtr.IsZplus()) || - ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ; + bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || + ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtExtr.IsZplus()) || + ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ; // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; // assegno i punti di inizio e fine al gruppo del percorso - m_pGeomDB->SetInfo( nPxId, KEY_START, vPtStart[0]); //<-------- - m_pGeomDB->SetInfo( nPxId, KEY_END, vPtStart[0]); //<-------- + m_pGeomDB->SetInfo( nPxId, KEY_START, ptStart) ; + m_pGeomDB->SetInfo( nPxId, KEY_END, ptStart) ; // assegno l'elevazione massima m_pGeomDB->SetInfo( nPxId, KEY_ELEV, dElev) ; - // Imposto dati comuni + // Imposto dati comuni SetPathId( nPxId) ; SetToolDir( vtTool) ; - // Eseguo la lavorazione del chunk (c)-esimo modificato per lati aperti a seconda del tipo di lavorazione richiesto + // Eseguo la lavorazione a seconda del tipo switch ( m_Params.m_nSubType) { - case POCKET_SUB_ZIGZAG: - if ( ! AddZigZag( pSrfPock, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, nPathId)) + case POCKET_SUB_ZIGZAG : + if ( ! AddZigZag( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, nPathId)) return false ; break ; - case POCKET_SUB_ONEWAY: - if ( ! AddOneWay( pSrfPock, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + case POCKET_SUB_ONEWAY : + if ( ! AddOneWay( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) return false ; break ; - case POCKET_SUB_SPIRALIN: - if ( ! AddSpiralIn( pSrfPock, vPtStart, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, vbMidOpen, vPtMidOpen, vVtMidOut, nPathId)) + case POCKET_SUB_SPIRALIN : + if ( ! AddSpiralIn( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, bMidOpen, ptMidOpen, vtMidOut, nPathId)) return false ; break ; - case POCKET_SUB_SPIRALOUT: - if ( ! AddSpiralOut( pSrfPock, vPtStart, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, nPathId)) + case POCKET_SUB_SPIRALOUT : + if ( ! AddSpiralOut( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, nPathId)) return false ; break ; } } - m_nPockets++ ; + // incremento numero di svuotature + ++ m_nPockets ; return true ; - } //---------------------------------------------------------------------------- @@ -1992,12 +1810,12 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v //---------------------------------------------------------------------------- bool -Pocketing::VerifyPathFromBottom( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool) +Pocketing::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) { - // se non è svuotatura dal basso in alto, esco + // se non è svuotatura dal basso in alto, esco if ( vtTool.z > MIN_ZDIR_TOP_TOOL) return true ; - // se c'è testa non dall'alto o tavola basculante, esco + // se c'è testa non dall'alto o tavola basculante, esco if ( ! m_bAboveHead || m_bTiltingTab) return true ; // recupero dati di eventuale rinvio da sotto @@ -2010,40 +1828,31 @@ Pocketing::VerifyPathFromBottom( const ISurfFlatRegion* pSrfPock, const Vector3d double dMinDist = INFINITO ; Vector3d vtMinDir ; VCT3DVECTOR vDir ; - - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; c++) { - for ( int l = 0 ; l < pSrfPock->GetLoopCount( c) ; l++) { - PtrOwner pCompo( GetCurveComposite( pSrfPock->GetLoop( c, l))) ; - if ( IsNull( pCompo)) - return false ; - - double dParS, dParE ; pCompo->GetDomain( dParS, dParE) ; - for ( double dPar = dParS ; dPar < dParE + EPS_PARAM ; dPar += 0.5) { - // distanza minima del punto e relativa direzione dal contorno del grezzo - Point3d ptP ; double dCurrDist = INFINITO ; Vector3d vtCurrDir ; - if ( pCompo->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptP) && - GetMinDistanceFromRawSide( m_nPhase, ptP, 0, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dCurrDist, vtCurrDir)) { - if ( dCurrDist < dMinDist - 10 * EPS_SMALL && - find_if( vDir.begin(), vDir.end(), [&]( const Vector3d& vtV) { return vtCurrDir * vtV > cos(15 * DEGTORAD); }) == vDir.end()) { - // inserisco la direzione tra quelle già esplorate - vDir.emplace_back( vtCurrDir) ; - // determino la distanza di tutti gli altri punti dal contorno del grezzo lungo questa direzione - for ( double dPar2 = dParS; dPar2 < dParE + EPS_PARAM; dPar2 += 0.5) { - if ( abs( dPar2 - dPar) > EPS_PARAM) { - Point3d ptQ ; - double dQDist ; - if ( pCompo->GetPointD1D2( dPar2, ICurve::FROM_MINUS, ptQ) && - GetDistanceFromRawSide( m_nPhase, ptQ, vtCurrDir, dQDist) && dQDist > dCurrDist) - dCurrDist = dQDist ; - } - } - // se la massima distanza trovata è inferiore al minimo, lo aggiorno - if ( dCurrDist < dMinDist) { - dMinDist = dCurrDist ; - vtMinDir = vtCurrDir ; - } + double dParS, dParE ; pCompo->GetDomain( dParS, dParE) ; + for ( double dPar = dParS ; dPar < dParE + EPS_PARAM ; dPar += 0.5) { + // distanza minima del punto e relativa direzione dal contorno del grezzo + Point3d ptP ; double dCurrDist = INFINITO ; Vector3d vtCurrDir ; + if ( pCompo->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptP) && + GetMinDistanceFromRawSide( m_nPhase, ptP, 0, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dCurrDist, vtCurrDir)) { + if ( dCurrDist < dMinDist - 10 * EPS_SMALL && + find_if( vDir.begin(), vDir.end(), [&](const Vector3d& vtV){ return vtCurrDir * vtV > cos( 15 * DEGTORAD) ; }) == vDir.end()) { + // inserisco la direzione tra quelle già esplorate + vDir.emplace_back( vtCurrDir) ; + // determino la distanza di tutti gli altri punti dal contorno del grezzo lungo questa direzione + for ( double dPar2 = dParS ; dPar2 < dParE + EPS_PARAM ; dPar2 += 0.5) { + if ( abs( dPar2 - dPar) > EPS_PARAM) { + Point3d ptQ ; + double dQDist ; + if ( pCompo->GetPointD1D2( dPar2, ICurve::FROM_MINUS, ptQ) && + GetDistanceFromRawSide( m_nPhase, ptQ, vtCurrDir, dQDist) && dQDist > dCurrDist) + dCurrDist = dQDist ; } } + // se la massima distanza trovata è inferiore al minimo, lo aggiorno + if ( dCurrDist < dMinDist) { + dMinDist = dCurrDist ; + vtMinDir = vtCurrDir ; + } } } } @@ -2062,10 +1871,16 @@ Pocketing::VerifyPathFromBottom( const ISurfFlatRegion* pSrfPock, const Vector3d //---------------------------------------------------------------------------- bool -Pocketing::GeneratePocketingPv( int nPathId, const ISurfFlatRegion* pSrfPock) +Pocketing::GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) { // creo copia della curva composita - PtrOwner pSfr( CloneSurfFlatRegion( pSrfPock)) ; + PtrOwner pCrv( pCompo->Clone()) ; + if ( IsNull( pCrv)) + return false ; + // calcolo la regione + SurfFlatRegionByContours SfrCntrRr ; + SfrCntrRr.AddCurve( Release( pCrv)) ; + PtrOwner pSfr( SfrCntrRr.GetSurf()) ; if ( IsNull( pSfr)) return false ; // ne recupero il contorno @@ -2073,11 +1888,11 @@ Pocketing::GeneratePocketingPv( int nPathId, const ISurfFlatRegion* pSrfPock) pCrv2.Set( pSfr->GetLoop( 0, 0)) ; if ( IsNull( pCrv2)) return false ; - // inserisco la curva nel DB + // inserisco la curva nel DB int nC2Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv2)) ; if ( nC2Id == GDB_ID_NULL) return false ; - // assegno nome e colore + // assegno nome e colore m_pGeomDB->SetName( nC2Id, MCH_PV_CUT) ; m_pGeomDB->SetMaterial( nC2Id, RED) ; // eventuali altri contorni ( interni di contornatura chiusa) @@ -2127,7 +1942,7 @@ GetCurveRadius( const ICurve* pCrv) //---------------------------------------------------------------------------- bool -Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) { // recupero distanze di sicurezza @@ -2141,411 +1956,175 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; double dStep = dElev / nStep ; + // determino il riferimento di base della svuotatura + Frame3d frPocket ; + Point3d ptCen ; pCompo->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtExtr) ; + frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; + + ICRVCOMPOPOVECTOR vpCrvs ; + int nOffsCrvNbr = 0 ; + + // verifico se si tratta di caso ottimizzato + bool bOptimizedZigZag = false ; + bool bOutRawLeadIn = false ; + if ( ! OptimizedZigZag( nPathId, vtTool, dDepth, dSafeZ, frPocket, bOptimizedZigZag, vpCrvs)) + return false ; + if ( bOptimizedZigZag && ! vpCrvs.empty()) { + nOffsCrvNbr = 1 ; + // verifico se attacco fuori dal grezzo + Point3d ptStart ; + vpCrvs[0]->GetStartPoint( ptStart) ; + Vector3d vtDir ; + vpCrvs[0]->GetStartDir( vtDir) ; + ptStart += -vtDir * ( m_TParams.m_dDiam / 2 + dSafeZ) ; + ptStart.ToGlob( frPocket) ; + ptStart += - vtTool * dDepth ; + double dTestElev ; + if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) || dTestElev < EPS_SMALL) + bOutRawLeadIn = true ; + // sistemo attacco (per essere completamente fuori dal grezzo) + if ( bOutRawLeadIn || m_bOpenOutRaw) + vpCrvs[0]->ExtendStartByLen( m_TParams.m_dDiam / 2 + dSafeZ) ; + } + + // se non ottimizzato e utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore + if ( ( ! bOptimizedZigZag || ! ( bOutRawLeadIn || m_bOpenOutRaw)) && m_TParams.m_nType == TT_MILL_NOTIP) { + if ( ! LeadInIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; + } + } + + // se caso non ottimizzato calcolo curva offsettata del raggio utensile + sovramateriale + (se non lucidatura) extra double dTRad = m_TParams.m_dDiam / 2 ; double dOffs = dTRad + GetOffsR() ; - double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min(0.1 * m_TParams.m_dDiam, 2.0) : 0) ; - - // vettore delle curve esterne Offsettate (per attacchi) e numero di Chunks - ICRVCOMPOPOVECTOR vCrvExt ; - int nChunks = 0 ; - - // copia della mia superificie - PtrOwner pSrfToPock( CloneSurfFlatRegion( pSrfPock)) ; - if ( IsNull( pSrfToPock)) - return false ; - - // scorro tutti i Chunks della regione per svuotarli - for ( int c = 0 ; c < pSrfToPock->GetChunkCount() ; c++) { - - // copio il Chunk (c)-esimo - PtrOwner pSrfChunk( CloneSurfFlatRegion( pSrfToPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) - return false ; - // superficie per ingressi ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunk)) ; - - // determino il riferimento in base alla svuotatura - Frame3d frPocket ; - Point3d ptCen ; pSrfToPock->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - - // porto la superificie nel nuovo sistema di riferimento - pSrfChunk->ToLoc( frPocket) ; - - // verifico se si tratta di caso ottimizzato - bool bOptimizedZigZag = false ; - bool bOutRawLeadIn = false ; - ICRVCOMPOPOVECTOR vpCrvs ; // vettore con i paths per il Chunk (c)-esimo - - if ( ! OptimizedZigZag( pSrfChunk, vtTool, dDepth, dSafeZ, frPocket, bOptimizedZigZag, vpCrvs)) - return false ; - if ( bOptimizedZigZag && ! vpCrvs.empty()) { - nChunks = 1; - // verifico se attacco fuori dal grezzo - Point3d ptStart ; - vpCrvs[0]->GetStartPoint( ptStart) ; - Vector3d vtDir ; - vpCrvs[0]->GetStartDir( vtDir) ; - ptStart += -vtDir * ( m_TParams.m_dDiam / 2 + dSafeZ) ; - ptStart.ToGlob( frPocket) ; - ptStart += -vtTool * dDepth ; - double dTestElev ; - if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) || dTestElev < EPS_SMALL) - bOutRawLeadIn = true ; - // sistemo attacco (per essere completamente fuori dal grezzo) - if ( bOutRawLeadIn || m_bOpenOutRaw) - vpCrvs[0]->ExtendStartByLen( m_TParams.m_dDiam / 2 + dSafeZ) ; - } - - // se non ottimizzato e utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore - if (( ! bOptimizedZigZag || ! ( bOutRawLeadIn || m_bOpenOutRaw)) && m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false; - } - } - - // se non sono nel caso ottimizzato, effettuo il primo Offset della regione e controllo quanti Chunks ottengo... - if ( ! bOptimizedZigZag) { - if ( ! pSrfChunk->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - nChunks = pSrfChunk->GetChunkCount() ; // facendo il primo Offset il Chunk (c)-esimo può generare altri Chunks... - } - - // tratto ogni Chunk ottenuto come se fosse una superficie singola, quindi con la propria svuotatura - bool bStart = true ; // controllo se prima curva - for ( int cc = 0 ; cc < nChunks ; cc++) { // per ognuno di questi Chunks... - - PtrOwner pSrfZigZag( GetSurfFlatRegion( pSrfChunk->CloneChunk( cc))) ; - if ( IsNull( pSrfZigZag)) - return false ; - - if ( ! bOptimizedZigZag) { - vpCrvs.clear() ; - if ( ! CalcZigZag( pSrfZigZag, vpCrvs)) - return false ; - } - - // se lucidatura - if ( m_TParams.m_nType == TT_MILL_POLISHING) { - // ciclo sui percorsi - for (int k = 0; k < int( vpCrvs.size()); ++k) { - // se attacco a scivolo - if ( GetLeadInType() == POCKET_LI_GLIDE) { - double dU; - vpCrvs[k]->GetParamAtLength(m_Params.m_dLiTang, dU); - vpCrvs[k]->AddJoint(dU); - Point3d ptStart; - vpCrvs[k]->GetStartPoint(ptStart); - vpCrvs[k]->ModifyStart(ptStart + vtTool * m_Params.m_dLiElev); - } - // se uscita a scivolo - if ( GetLeadOutType() == POCKET_LO_GLIDE) { - double dLen, dU; - vpCrvs[k]->GetLength(dLen); - vpCrvs[k]->GetParamAtLength(dLen - m_Params.m_dLoTang, dU); - vpCrvs[k]->AddJoint(dU); - Point3d ptEnd; - vpCrvs[k]->GetEndPoint(ptEnd); - vpCrvs[k]->ModifyEnd(ptEnd + vtTool * m_Params.m_dLiElev); - } - } - } - - // inserisco i movimenti di svuotatura - for ( int j = 1 ; j <= nStep ; ++j) { - // ciclo sui percorsi - int nPath = int( vpCrvs.size()); - for ( int k = 0 ; k < nPath ; ++k) { - // ciclo sulle curve elementari - int nMaxInd = vpCrvs[k]->GetCurveCount() - 1; - for ( int i = 0 ; i <= nMaxInd ; ++i) { - // curva corrente - const ICurve* pCrvC = vpCrvs[k]->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false; - pCurve->ToGlob( frPocket) ; - // aggiungo affondamento - pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // --- se PRIMA ENTITA' --- - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // determino inizio attacco - Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) - return false; - // determino elevazione su inizio attacco - double dStElev ; - GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev) ; - dStElev = max(dStElev, j * dStep) ; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev); - if ( bUnderRaw) - dStElev = max( dStElev, j * dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se ottimizzata e attacco nel grezzo - if ( bOptimizedZigZag && !( bOutRawLeadIn || m_bOpenOutRaw)) { - // se richiesto attacco a zigzag o a spirale, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX) { - ptP1 += vtExtr * dStElev ; - dStElev = 0 ; - } - } - // se inizio, approccio globale al punto iniziale - if ( bStart) { - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutRawLeadIn || m_bOpenOutRaw)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; - return false ; - } - bStart = false ; - } - // altrimenti, approccio di collegamento - else { - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutRawLeadIn || m_bOpenOutRaw)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false; - } - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, - bSplitArcs, bOutRawLeadIn || m_bOpenOutRaw)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - } - // elaborazioni sulla curva corrente - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint(ptP3) ; - SetFeed( GetFeed()) ; - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // --- se ULTIMA ENTITA' --- - if ( i == nMaxInd) { - // dati fine entità - Point3d ptEnd; - pCurve->GetEndPoint(ptEnd); - Vector3d vtEnd; - pCurve->GetEndDir(vtEnd); - // aggiungo uscita - double dEndElev = dElev; - Point3d ptP1; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev, true)) { - m_pMchMgr->SetLastError(2416, "Error in Pocketing : LeadOut not computable") ; - return false; - } - dEndElev = max( dEndElev, j * dStep) ; - // se lucidatura o caso ottimizzato e ultimo percorso di ultimo step, aggiungo retrazione - if (( m_TParams.m_nType == TT_MILL_POLISHING || bOptimizedZigZag) && k == nPath - 1 && j == nStep) { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Retract not computable") ; - return false; - } - } - // altrimenti, aggiungo retrazione di collegamento - else { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError(2418, "Error in Pocketing : Link not computable"); - return false; - } - } - } - } - } - } - } - - // Curva esterna (per passare vicino ai bordi) - - // se lucidatura o caso ottimizzato, non aggiungo contorno - if ( m_TParams.m_nType == TT_MILL_POLISHING /* || bOptimizedZigZag*/) - return true; - - bool bChangeFirst = true; - Point3d ptLastEnd; - - // Copio il Chunk c-esimo e lo porto nel sistema di riferimento della svuotatura - pSrfChunk.Set( CloneSurfFlatRegion( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) - return false ; - pSrfChunk->ToLoc( frPocket) ; - - // creo l'Offset per le curve estene - if ( ! pSrfChunk->Offset( -dOffs, ICurve::OFF_FILLET)) { + double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ; + OffsetCurve OffsCrv ; + if ( ! bOptimizedZigZag) { + if ( ! OffsCrv.Make( pCompo, - ( dOffs + dExtra), ICurve::OFF_FILLET)) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } + nOffsCrvNbr = OffsCrv.GetCurveCount() ; + } - // creo un vettore con tutti i loop formati, aggiustando i loro punti iniziali - ICRVCOMPOPOVECTOR vCrvLoops ; - for ( int cc = 0 ; cc < pSrfChunk->GetChunkCount() ; cc++) { - for ( int l = 0 ; l < pSrfChunk->GetLoopCount( cc) ; l++) { + // ciclo sulle curve risultanti + bool bStart = true ; + while ( nOffsCrvNbr > 0) { - PtrOwner pOffs( CreateCurveComposite()) ; - if ( IsNull( pOffs) || ! pOffs->AddCurve( pSrfChunk->GetLoop( cc, l))) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - - // se richiesto, la inverto - if ( m_Params.m_bInvert) - pOffs->Invert() ; - - // resetto le proprietà per attacchi - ResetCurveAllTempProp( pOffs) ; - - // aggiusto il punto iniziale - AdjustContourStart( pOffs) ; - - // verifico archi - VerifyArcs( pOffs) ; - - vCrvLoops.emplace_back( Release( pOffs)) ; - } - } - - // se sono nel caso ottimizzato devo togliere il loop esterno - if ( bOptimizedZigZag) { - double dMaxArea = -INFINITO ; int nJumpInd = 0 ; - for ( int i = 0 ; i < vCrvLoops.size() ; i++) { - double dArea ; vCrvLoops[i]->GetAreaXY( dArea) ; - if ( dArea > dMaxArea) { - dMaxArea = dArea ; - nJumpInd = i ; - } - } - ICRVCOMPOPOVECTOR vCrvHelp ; - for ( int i = 0 ; i < vCrvLoops.size() ; i++) { - if ( i != nJumpInd) - vCrvHelp.emplace_back( vCrvLoops[i]->Clone()) ; - } - vCrvLoops.clear() ; - vCrvLoops.resize( vCrvHelp.size()) ; - for ( int i = 0 ; i < vCrvHelp.size() ; i++) - vCrvLoops[i].Set( Release( vCrvHelp[i])) ; - } - - // guardo il punto finale in cui si trova la fresa - Point3d ptEnd ; - if( vpCrvs.size() > 0) - vpCrvs.back()->GetEndPoint( ptEnd) ; - - // ordino le curve a partire dal punto finale raggiunto della fresa - Point3d ptRef = ptEnd ; - double dMinDist = INFINITO ; - int nIndexSwitch = -1 ; - for ( int i = -1 ; i < vCrvLoops.size() - 1 ; i++) { - for ( int j = i + 1 ; j < vCrvLoops.size() ; j++) { - Point3d ptS ; vCrvLoops[j]->GetStartPoint( ptS) ; - if ( Dist( ptS, ptRef) < dMinDist) { - dMinDist = Dist( ptS, ptRef) ; - nIndexSwitch = j ; - } - } - if ( nIndexSwitch != i + 1) { - PtrOwner pCrvClosest( vCrvLoops[nIndexSwitch]->Clone()) ; - vCrvLoops[nIndexSwitch].Set(Release( vCrvLoops[i+1])) ; - vCrvLoops[i+1].Set( Release( pCrvClosest)) ; - } - vCrvLoops[i+1]->GetEndPoint( ptRef) ; - dMinDist = INFINITO ; - } - - for( int u = 0 ; u < vCrvLoops.size() ; u++) { - - // recupero la prima curva di offset disponibile - PtrOwner pOffs( CreateCurveComposite()); - if ( IsNull( pOffs) || ! pOffs->AddCurve( vCrvLoops[u]->Clone())) { + if ( bOptimizedZigZag) + nOffsCrvNbr = 0 ; // setto a zero per non rientrare nel while + else { + // recupero la prima curva di offset + PtrOwner pOffs( CreateCurveComposite()) ; + if ( IsNull( pOffs) || ! pOffs->AddCurve( OffsCrv.GetLongerCurve())) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false; + return false ; } + nOffsCrvNbr = OffsCrv.GetCurveCount() ; - // aggiungo la lavorazione di questa curva - Point3d ptP1 ; - for ( int j = 1; j <= nStep; ++j) { - // ciclo sulle curve elementari - int nMaxInd = pOffs->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++i) { + // porto la curva nel riferimento della svuotatura + pOffs->ToLoc( frPocket) ; + + // calcolo i percorsi di svuotatura + vpCrvs.clear() ; + if ( ! CalcZigZag( pOffs, vpCrvs)) + return false ; + } + + // se lucidatura + if ( m_TParams.m_nType == TT_MILL_POLISHING) { + // ciclo sui percorsi + for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { + // se attacco a scivolo + if ( GetLeadInType() == POCKET_LI_GLIDE) { + double dU ; + vpCrvs[k]->GetParamAtLength( m_Params.m_dLiTang, dU) ; + vpCrvs[k]->AddJoint( dU) ; + Point3d ptStart ; + vpCrvs[k]->GetStartPoint( ptStart) ; + vpCrvs[k]->ModifyStart( ptStart + vtTool * m_Params.m_dLiElev) ; + } + // se uscita a scivolo + if ( GetLeadOutType() == POCKET_LO_GLIDE) { + double dLen, dU ; + vpCrvs[k]->GetLength( dLen) ; + vpCrvs[k]->GetParamAtLength( dLen - m_Params.m_dLoTang, dU) ; + vpCrvs[k]->AddJoint( dU) ; + Point3d ptEnd ; + vpCrvs[k]->GetEndPoint( ptEnd) ; + vpCrvs[k]->ModifyEnd( ptEnd + vtTool * m_Params.m_dLiElev) ; + } + } + } + + // inserisco i movimenti di svuotatura + for ( int j = 1 ; j <= nStep ; ++ j) { + // ciclo sui percorsi + int nPath = int( vpCrvs.size()) ; + for ( int k = 0 ; k < nPath ; ++ k) { + // ciclo sulle curve elementari + int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { // curva corrente - const ICurve* pCrvC = pOffs->GetCurve( i) ; + const ICurve* pCrvC = vpCrvs[k]->GetCurve( i) ; // copio la curva PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; pCurve->ToGlob( frPocket) ; // aggiungo affondamento - pCurve->Translate( -vtTool * ( dDepth - dElev + j * dStep)) ; - // --- se PRIMA ENTITA' --- - if ( i == 0) { - // dati inizio entità + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità Point3d ptStart ; pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo - if ( j == 1) { - // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) - return false ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) - dStElev = max( dStElev, dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * dStElev; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev) ; + dStElev = max( dStElev, j * dStep) ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw) + dStElev = max( dStElev, j * dStep) ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se ottimizzata e attacco nel grezzo + if ( bOptimizedZigZag && ! ( bOutRawLeadIn || m_bOpenOutRaw)) { + // se richiesto attacco a zigzag o a spirale, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX) { + ptP1 += vtExtr * dStElev ; dStElev = 0 ; } - // approccio al punto iniziale - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { + } + // se inizio, approccio globale al punto iniziale + if ( bStart) { + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutRawLeadIn || m_bOpenOutRaw)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + bStart = false ; + } + // altrimenti, approccio di collegamento + else { + if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutRawLeadIn || m_bOpenOutRaw)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs)) { - m_pMchMgr->SetLastError(2415, "Error in Pocketing : LeadIn not computable"); - return false; - } } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs)) { - m_pMchMgr->SetLastError(2418, "Error in Pocketing : Link not computable") ; - return false; - } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, + bSplitArcs, bOutRawLeadIn || m_bOpenOutRaw)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; } } // elaborazioni sulla curva corrente @@ -2563,39 +2142,186 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c Vector3d vtN = pArc->GetNormVersor() ; Point3d ptP3 ; pArc->GetEndPoint( ptP3) ; - SetFeed( GetFeed()); + SetFeed( GetFeed()) ; if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; } - // se ultima entità + // se ultima entità if ( i == nMaxInd) { - // se ultimo step, uscita e retrazione di collegamento - if ( j == nStep) { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - double dEndElev = dElev ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + double dEndElev = dElev ; + Point3d ptP1 ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev, true)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + dEndElev = max( dEndElev, j * dStep) ; + // se lucidatura o caso ottimizzato e ultimo percorso di ultimo step, aggiungo retrazione + if ( ( m_TParams.m_nType == TT_MILL_POLISHING || bOptimizedZigZag) && k == nPath - 1 && j == nStep) { + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Retract not computable") ; return false ; } - // se ci sono ancora curve, aggiungo retrazione di collegamento - if ( pOffs->GetCurveCount() > 0) { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } + } + // altrimenti, aggiungo retrazione di collegamento + else { + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; } - // altrimenti retrazione finale - else { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Retract not computable") ; - return false ; - } + } + } + } + } + } + } + + // se lucidatura o caso ottimizzato, non aggiungo contorno + if ( m_TParams.m_nType == TT_MILL_POLISHING || bOptimizedZigZag) + return true ; + + // calcolo seconda curva offsettata del raggio utensile + sovramateriale + OffsetCurve OffsCrv2 ; + if ( ! OffsCrv2.Make( pCompo, - dOffs, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + + // ciclo sulle curve risultanti + while ( OffsCrv2.GetCurveCount() > 0) { + + // recupero la prima curva di offset + PtrOwner pOffs2( CreateCurveComposite()) ; + if ( IsNull( pOffs2) || ! pOffs2->AddCurve( OffsCrv2.GetLongerCurve())) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + VerifyArcs( pOffs2) ; + + // se richiesto, la inverto + if ( m_Params.m_bInvert) + pOffs2->Invert() ; + + // sposto l'inizio a metà del tratto più lungo + AdjustContourStart( pOffs2) ; + + // aggiungo la lavorazione di questa curva + Point3d ptP1 ; + for ( int j = 1 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + int nMaxInd = pOffs2->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pOffs2->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino inizio attacco + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw) + dStElev = max( dStElev, dStep) ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * dStElev ; + dStElev = 0 ; + } + // approccio al punto iniziale + if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità + if ( i == nMaxInd) { + // se ultimo step, uscita e retrazione di collegamento + if ( j == nStep) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // se ci sono ancora curve, aggiungo retrazione di collegamento + if ( OffsCrv2.GetCurveCount() > 0) { + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + } + // altrimenti retrazione finale + else { + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Retract not computable") ; + return false ; } } } @@ -2609,37 +2335,22 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c //---------------------------------------------------------------------------- bool -Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpCrvs) +Pocketing::CalcZigZag( const ICurveComposite* pOffs, + ICRVCOMPOPOVECTOR& vpCrvs) { - - // check parametri - if ( pSrfZigZag == nullptr) - return true ; - - // per tagli delle curve non sul secondo offset per zone non svuotate - double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min(0.1 * m_TParams.m_dDiam, 2.0) : 0) ; - - // creo il vettore dei contorni - ICRVCOMPOPOVECTOR vFirstOff ; - for ( int c = 0 ; c < pSrfZigZag->GetChunkCount(); c++) { - for ( int l = 0 ; l < pSrfZigZag->GetLoopCount(c); l++) { - vFirstOff.emplace_back( GetCurveComposite( pSrfZigZag->GetLoop( c, l)->Clone())) ; - } - } - // ingombro del contorno offsettato BBox3d b3Pocket ; - vFirstOff[0]->GetLocalBBox( b3Pocket) ; + pOffs->GetLocalBBox( b3Pocket) ; Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; // lunghezza del contorno offsettato - double dLen ; vFirstOff[0]->GetLength( dLen) ; + double dLen ; pOffs->GetLength( dLen) ; // passi in Y - int nYStep = static_cast< int >( ceil(( dDimY - 30 * EPS_SMALL) / GetSideStep())) ; + int nYStep = static_cast( ceil( ( dDimY - 30 * EPS_SMALL) / GetSideStep())) ; double dYStep = ( nYStep > 0 ? ( dDimY - 30 * EPS_SMALL) / nYStep : 0) ; - int nRef = (( nYStep + ( m_Params.m_bInvert ? 0 : 1)) % 2) ; + int nRef = ( ( nYStep + ( m_Params.m_bInvert ? 0 : 1)) % 2) ; // tratto valido struct Section { @@ -2648,78 +2359,72 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC Point3d ptE ; double dOs ; double dOe ; - int nOffIndS ; - int nOffIndE ; } ; - - struct ParIsland { - double dU ; - int nInd ; - } ; - // raccolta di tratti - typedef vector> VECVECSECT ; VECVECSECT vvSec ; + typedef vector> VECVECSECT ; + + VECVECSECT vvSec ; vvSec.resize( nYStep + 1) ; // calcolo le linee di svuotatura int nCount = 0 ; - for ( int i = 0 ; i <= nYStep ; ++i) { + for ( int i = 0 ; i <= nYStep ; ++ i) { // determino senso bool bPlus = (( i % 2) == nRef) ; // definisco la linea PtrOwner pLine( CreateCurveLine()) ; const double EXP_LEN = 1.0 ; Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ; - if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { + if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - - if ( ! bPlus) - pLine->Invert() ; - - // calcolo la classificazione della linea rispetto alla superificie + // calcolo la classificazione della curva rispetto al contorno esterno offsettato + IntersCurveCurve intCC( *pLine, *pOffs) ; CRVCVECTOR ccClass ; - pSrfZigZag->GetCurveClassification( *pLine, EPS_SMALL, ccClass) ; - for ( int j = 0 ; j < ccClass.size() ; j++) { - if ( ccClass[j].nClass == CRVC_IN) { // memorizzo il segmento - Section currSec; - currSec.bActive = true; - PtrOwner pSeg( GetCurveLine( pLine->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) ; - Point3d ptS, ptE ; - pSeg->GetStartPoint( ptS) ; pSeg->GetEndPoint( ptE) ; - currSec.ptS = ptS ; currSec.ptE = ptE ; - for ( int k = 0 ; k < vFirstOff.size() ; k++) { - if ( vFirstOff[k]->IsPointOn( ptS)) { - currSec.nOffIndS = k ; - double dUOS; vFirstOff[k]->GetParamAtPoint( ptS, dUOS) ; - currSec.dOs = dUOS ; - } - if ( vFirstOff[k]->IsPointOn( ptE)){ - currSec.nOffIndE = k ; - double dUOE; vFirstOff[k]->GetParamAtPoint( ptE, dUOE) ; - currSec.dOe = dUOE ; - } - } - vvSec[i].emplace_back( currSec) ; - ++nCount ; // numero di segmenti inseriti - } + if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + // determino gli intervalli di curva da conservare + Intervals inOk ; + for ( auto& ccOne : ccClass) { + if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M) + inOk.Add( ccOne.dParS, ccOne.dParE) ; + } + // inserisco i tratti validi (secondo X+ i pari, secondo X- i dispari) + double dParS, dParE ; + bool bFound = ( bPlus ? inOk.GetFirst( dParS, dParE) : inOk.GetLast( dParE, dParS)) ; + while ( bFound) { + // determino i dati della sezione + Section Sect ; + Sect.bActive = true ; + pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, Sect.ptS) ; + pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, Sect.ptE) ; + pOffs->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ; + pOffs->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ; + // inserisco nel contenitore + vvSec[i].emplace_back( Sect) ; + ++ nCount ; + // recupero successivo intervallo + bFound = ( bPlus ? inOk.GetNext( dParS, dParE) : inOk.GetPrev( dParE, dParS)) ; } } - int nStatus = 0 ; // 0 -> inizio oppure ho inserito una parte di isola | 2 -> sto inserendo un segmento - Point3d ptS_ref ; - PtrOwner plastLine( CreateCurveLine()) ; + // dominio del contorno + double dUmin, dUmax ; + pOffs->GetDomain( dUmin, dUmax) ; + double dUspan = dUmax - dUmin ; // creo i percorsi di svuotatura vpCrvs.reserve( nCount) ; int nI = -1, nJ = -1 ; while ( true) { // se sezione non valida - if ( nI < 0 || nJ < 0) { - // ricerco la prima valida ( il primo segmento con bActive messo a true) - for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++k) { - for (int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++l) { + if ( nI < 0 || nJ < 0) { + // ricerco la prima valida + for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++ k) { + for ( int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++ l) { if ( vvSec[k][l].bActive) { nI = k ; nJ = l ; @@ -2727,10 +2432,9 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC } } // se trovata, creo nuova curva composita - if ( nI >= 0 && nJ >= 0) { + if ( nI >= 0 && nJ >= 0) { // creo la curva vpCrvs.emplace_back( CreateCurveComposite()) ; - nStatus = 0 ; // aggiungo punto iniziale vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ; } @@ -2738,111 +2442,21 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC else break ; } - // determino senso + // determino senso bool bPlus = (( nI % 2) == nRef) ; - // aggiungo la sezione alla curva + // aggiungo la sezione alla curva Section& Sec = vvSec[nI][nJ] ; Sec.bActive = false ; vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ; - - if (vpCrvs[0]->GetCurveCount() == 9) - int a = 0; - - if ( nStatus == 0) { // primo segmento per il raccordo smussato - plastLine.Set( GetCurveLine( vpCrvs.back()->GetLastCurve()->Clone())) ; - plastLine->GetStartPoint( ptS_ref) ; - } - if ( nStatus == 2) { // ho precedentemente aggiunto il bordo di un'isola, quindi mi salvo il secondo segmento - PtrOwner pSeg1( GetCurveLine( vpCrvs.back()->GetLastCurve()->Clone())) ; - PtrOwner pCrvLink( CreateCurveComposite()) ; - PtrOwner pSeg2( GetCurveLine( plastLine->Clone())) ; - if ( CalcBoundedZigZagLink( pSeg2, pSeg1, vFirstOff, pCrvLink)) { // se riesco a creare una semicirconferenza ... - double dUE ; // paramtro finale della curva totale fino ad ora - vpCrvs[vpCrvs.size() - 1]->GetParamAtPoint( ptS_ref, dUE) ; // punto finale della curva totale fino ad ora - PtrOwner pCrvToSave( CreateCurveComposite()) ; // tratto di curva precedente a pSeg1, pCrvLink, pSeg2 - if( dUE != 0) // se il tratto di curva precedente esiste ... - pCrvToSave.Set(GetCurveComposite(vpCrvs[vpCrvs.size() - 1]->CopyParamRange( 0, dUE))) ; // ... lo salvo - pCrvToSave->AddCurve( Release( pSeg2)) ; // aggiungo al tratto precedente il pSeg1 (trimmed alla fine) - pCrvToSave->AddCurve( Release( pCrvLink)) ; // aggiungo la semicirconferenza - pCrvToSave->AddCurve( Release( pSeg1)) ; // aggiungo il pSeg2 (trimmed all'inizio) - vpCrvs[vpCrvs.size() - 1]->Clear() ; - vpCrvs[vpCrvs.size() - 1]->AddCurve( Release( pCrvToSave)) ; // sistemo il percorso - } - else { // ... se non ho creato una semicirconferenza cerco di smussare pSeg1 - pCrvLink - pSeg2 (pCrvlink è il tratto di isola) - double dUS, dUE, dUS_I, dUE_I ; - vpCrvs[vpCrvs.size() - 1]->GetDomain( dUS, dUE) ; // dominio del percorso - vpCrvs[vpCrvs.size() - 1]->GetParamAtPoint( ptS_ref, dUS) ; // dUS -> parametro della curva totale nel punto iniziale di pSeg1 - PtrOwner pCrvToSmooth( CreateCurveComposite()) ; // cuvra smussata pSeg1 - pCrvLink - pSeg2 - pCrvToSmooth->AddCurve(vpCrvs[vpCrvs.size() - 1]->CopyParamRange( dUS, dUE)); - - double dLen1, dLenI_s, dLenI_e, dLen2 ; - - PtrOwner pCrv1( CreateCurveLine()) ; // segmento pSeg1 - Point3d pt1, pt2; - pCrvToSmooth->GetFirstCurve()->GetStartPoint( pt1) ; - pCrvToSmooth->GetFirstCurve()->GetEndPoint( pt2) ; - pCrv1->Set( pt1, pt2) ; - PtrOwner pCrv2( CreateCurveLine()); // segmento pSeg2 - pCrvToSmooth->GetLastCurve()->GetStartPoint( pt1) ; - pCrvToSmooth->GetLastCurve()->GetEndPoint( pt2) ; - pCrv2->Set(pt1, pt2) ; - - Point3d ptSH, ptEH ; // punto iniziale sul pSeg1 - pCrv1->GetEndPoint( ptSH) ; vpCrvs[vpCrvs.size() - 1]->GetParamAtPoint( ptSH, dUS_I) ; // parametro sulla curva globale di inizio di pCrvLink - pCrv2->GetStartPoint( ptEH) ; vpCrvs[vpCrvs.size() - 1]->GetParamAtPoint( ptEH, dUE_I) ; // paramtro sulla curva globale di fine di pCrvLink - PtrOwner pCrvIsl( CreateCurveComposite()) ; // segmento pCrvLink - pCrvIsl->AddCurve(vpCrvs[vpCrvs.size() - 1]->CopyParamRange( dUS_I, dUE_I)) ; - - - pCrv1->GetLength( dLen1) ; // lunghezza di pSeg1 - pCrv2->GetLength( dLen2) ; // lunghezza di pSeg2 - pCrvIsl->GetFirstCurve()->GetLength( dLenI_s); // lunghezza prima curva di PCrvLink - pCrvIsl->GetLastCurve()->GetLength( dLenI_e) ; // lunghezza ultima curva di pCrvLink - - // raccordo tra pSeg1 e pCrvLink - double dTollLeft = 1 - ( dLen1 - ( m_TParams.m_dTDiam / 16)) / dLen1 ; // % parametro sinistro per smusso - double dTollRight = ( m_TParams.m_dTDiam / 16) / dLenI_s ; // % parametro destro di smusso - PtrOwner pCrv_1I( CreateCurveComposite()) ; // curva unione di pSeg1 e pCrvLink smussata - pCrv_1I->AddCurve( pCrv1->Clone()); pCrv_1I->AddCurve( pCrvIsl->Clone()) ; - ModifyCurveToSmooted( pCrv_1I, dTollLeft, dTollRight) ; - - double dUS_1IH, dUE_1IH, dToTLen ; - pCrv_1I->GetDomain( dUS_1IH, dUE_1IH) ; // dominio della curva smussata tra pSeg1 e PCrvLink - pCrv_1I->GetLength( dToTLen) ; // nuova lunghezza della curva smussata tra pSeg1 e pCrvLink - dTollLeft = 1 - ( dLenI_e - (m_TParams.m_dTDiam / 16)) / dLenI_e; // % paramtro sinistro per smusso - dTollRight = ( m_TParams.m_dTDiam / 16) / dLen2 ; // % parametro destro per smusso - PtrOwner pCrv_I2( CreateCurveComposite()) ; // curva unione del primo smusso con pSeg2 (il tutto smussato) - pCrv_I2->AddCurve( pCrv_1I->Clone()) ; pCrv_I2->AddCurve( pCrv2->Clone()) ; - ModifyCurveToSmooted( pCrv_I2, dTollLeft, dTollRight) ; - - PtrOwner pCrvToSave( CreateCurveComposite()) ; - if ( dUS != 0) - pCrvToSave->AddCurve(( vpCrvs[vpCrvs.size() - 1]->CopyParamRange( 0, dUS))) ; - - pCrvToSave->AddCurve( Release( pCrv_I2)) ; - vpCrvs[vpCrvs.size() - 1]->Clear() ; - vpCrvs[vpCrvs.size() - 1]->AddCurve(Release( pCrvToSave)) ; - - } - // pSeg2 ora diventa pSeg1 e il procedimento si itera per tutto il percorso - plastLine.Set( GetCurveLine( vpCrvs.back()->GetLastCurve()->Clone())) ; - plastLine->GetStartPoint( ptS_ref) ; - } // cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno - double dUstart = Sec.dOe ; - int nIndexIslandE = Sec.nOffIndE ; // isola di arrivo - double dUmin, dUmax ; - vFirstOff[nIndexIslandE]->GetDomain( dUmin, dUmax) ; - double dUspan = dUmax - dUmin ; - double dUref = ( bPlus ? INFINITO : -INFINITO) ; + double dUstart = Sec.dOe ; + double dUref = ( bPlus ? INFINITO : - INFINITO) ; int nNextI = -1 ; int nNextJ = -1 ; - int li = nJ + 1 ; - for (int k = nI ; k <= nI + 1 && k < int( vvSec.size()) ; ++k) { - for ( int l = li ; l < int( vvSec[k].size()) ; ++l) { - if ( ! vvSec[k][l].bActive) // se sezione non attiva... non la considero - continue ; - if ( vvSec[k][l].nOffIndS != nIndexIslandE) // se isola diversa... non la considero + int li = nJ + 1 ; + for ( int k = nI ; k <= nI + 1 && k < int( vvSec.size()) ; ++ k) { + for ( int l = li ; l < int( vvSec[k].size()) ; ++ l) { + if ( ! vvSec[k][l].bActive) continue ; double dU = vvSec[k][l].dOs ; if ( bPlus) { @@ -2866,17 +2480,17 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC } li = 0 ; } - // se trovato, controllo il contorno dell'isola + // se trovato, aggiungo il tratto di contorno e continuo if ( nNextI != -1) { PtrOwner pCopy ; if ( bPlus) { - if ( dUref > dUmax) + if ( dUref > dUmax) dUref -= dUspan ; - pCopy.Set( vFirstOff[nIndexIslandE]->CopyParamRange( dUstart, dUref)) ; + pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; if ( ! IsNull( pCopy)) { double dCLen ; pCopy->GetLength( dCLen) ; if ( dCLen > 0.5 * dLen) { - pCopy.Set( vFirstOff[nIndexIslandE]->CopyParamRange( dUref, dUstart)) ; + pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; if ( ! IsNull( pCopy)) pCopy->Invert() ; } @@ -2885,23 +2499,19 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC else { if ( dUref < dUmin) dUref += dUspan ; - pCopy.Set( vFirstOff[nIndexIslandE]->CopyParamRange( dUref, dUstart)) ; + pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; if ( ! IsNull( pCopy)) { pCopy->Invert() ; - double dCLen; pCopy->GetLength( dCLen) ; + double dCLen ; pCopy->GetLength( dCLen) ; if ( dCLen > 0.5 * dLen) - pCopy.Set( vFirstOff[nIndexIslandE]->CopyParamRange( dUstart, dUref)) ; + pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; } } - // controllo che nel percorso scelto non ritorni indietro superando la precendete passata BBox3d b3Copy ; if ( ! IsNull( pCopy)) pCopy->GetLocalBBox( b3Copy) ; - if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) { // tengo la curva (non ritorno indietro più dello step) - Point3d ptS, ptE ; + if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) { vpCrvs.back()->AddCurve( Release( pCopy)) ; - nStatus = 2 ; - // aggiungo il Link nI = nNextI ; nJ = nNextJ ; } @@ -2915,208 +2525,22 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC nJ = -1 ; } } - return true ; } //---------------------------------------------------------- bool -Pocketing::GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks, ISurfFlatRegion* pSrfToCut) { - - // controllo dei parametri - if ( vFirstOffs.size() == 0 || vCrvs.size() < vFirstOffs.size() ) - return false ; - pSrfToCut->Clear() ; - - // 1) creo la regione esterna - PtrOwner pSrfExtern( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfExtern)) - return false ; - - for ( int i = 0 ; i < vFirstOffs.size() ; i++) { - if ( i == 0) - pSrfExtern->AddExtLoop( vFirstOffs[i]->Clone()) ; - else { - ICurve* pCrvIntLoop( vFirstOffs[i]->Clone()) ; - if ( ! pCrvIntLoop->Invert() || ! pSrfExtern->AddIntLoop( pCrvIntLoop)) - return false ; - } - } - - // 2) Creo la regione svuotata dal Tool - PtrOwner pSrfTool( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfTool)) - return false ; - - for ( int i = 0 ; i < vCrvs.size(); i++) { - PtrOwner pSrfToolRegOffi( GetSurfFlatRegionFromFatCurve( vCrvs[i]->Clone(), m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; - if ( i == 0) - pSrfTool.Set( Release( pSrfToolRegOffi)) ; - else - pSrfTool->Add( *Release( pSrfToolRegOffi)) ; - } - - for ( int i = 0; i < vLinks.size(); i++) { - if ( ! IsNull( vLinks[i])) { - PtrOwner pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( vLinks[i]->Clone(), m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false)) ; - pSrfTool->Add( *Release( pSrfToolRegLinki)) ; - } - } - - // 3) Creo la regione contenente tutte le parti non svuotate - pSrfToCut->CopyFrom( pSrfExtern->Clone()) ; - if ( ! pSrfToCut->Subtract( *pSrfTool)) - return false ; - - return true ; -} - -//---------------------------------------------------------- -bool -Pocketing::CalcBoundedZigZagLink( ICurveLine* pCrv1, ICurveLine* pCrv2, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink, int nIndexCut) { - - // controllo dei parametri - if ( pCrv1 == nullptr || pCrv2 == nullptr) - return false ; - if ( ! ( nIndexCut == 1 || nIndexCut == 2 || nIndexCut == 3 || nIndexCut == 4)) - return false ; - pCrvLink->Clear() ; - - // prendo i parametri per il raccordo - Vector3d vtS, vtE, vtH ; - pCrv1->GetEndDir( vtS) ; - pCrv2->GetStartDir( vtE) ; - Point3d ptS, ptE, ptE1, ptS2 ; - pCrv1->GetEndPoint( ptS) ; - pCrv2->GetStartPoint( ptE) ; - vtH = ptE - ptS ; - double dLen1, dLen2 ; - pCrv1->GetLength( dLen1) ; - pCrv2->GetLength( dLen2) ; - double dUS1, dUE1, dUS2, dUE2 ; - pCrv1->GetDomain( dUS1, dUE1) ; - pCrv2->GetDomain( dUS2, dUE2) ; - double dAngle, dAngleH ; - double dDist = Dist( ptS, ptE) ; - - PtrOwner pCrvH1( CreateCurveLine()) ; - PtrOwner pCrvH2( CreateCurveLine()) ; - PtrOwner pCrvTempLink( CreateCurveComposite()) ; - PtrOwner pCrvTest( CreateCurveComposite()) ; - - if ( pCrvH1 == nullptr || pCrvH2 == nullptr || pCrvTempLink == nullptr || pCrvTest == nullptr) - return false ; - - if ( vtS.GetAngle( vtE, dAngle) && abs( dAngle) < 180 + 5 * EPS_SMALL && abs( dAngle) > 180 - 5 * EPS_SMALL - && vtH.GetAngle( vtE, dAngleH) && abs( dAngleH) < 90 + 5 * EPS_SMALL && abs( dAngleH) > 90 - 5 * EPS_SMALL && dLen1 > dDist && dLen2 > dDist) { - // creo una semi circonferenza - double dRad = dDist / 2 ; - ICurveArc* pSemiCir( CreateCurveArc()) ; - Point3d ptNS, ptNE ; - - switch ( nIndexCut) - { - case 1: // taglio solo la prima - pCrv1->GetParamAtLength( dLen1 - dRad, dUE1) ; - break ; - case 2: // taglio solo la seconda - pCrv2->GetParamAtLength( dRad, dUS2) ; - break ; - case 3: // taglio entrambe - pCrv1->GetParamAtLength( dLen1 - dRad, dUE1) ; - pCrv2->GetParamAtLength( dRad, dUS2) ; - break ; - default: - break ; - } - - pCrv1->GetPointD1D2( dUE1, ICurve::FROM_MINUS, ptNS); - pCrv2->GetPointD1D2( dUS2, ICurve::FROM_PLUS, ptNE); - if (pSemiCir->Set2PVN(ptNS, ptNE, vtS, Z_AX)) { - pCrvH1.Set(GetCurveLine(pCrv1->CopyParamRange(dUS1, dUE1))); - pCrvH2.Set(GetCurveLine(pCrv2->CopyParamRange(dUS2, dUE2))); - pCrvTempLink->AddCurve(pSemiCir->Clone()); - } - } - else if( dLen1 - m_TParams.m_dDiam / 4 > 50 * EPS_SMALL && dLen2 - m_TParams.m_dDiam / 4 > 50 * EPS_SMALL) { - // se non riesco collego con un segmento ? no, esco dalla funzione - return false ; - - switch ( nIndexCut) - { - case 1: // taglio solo la prima - pCrv1->GetParamAtLength( dLen1 - m_TParams.m_dDiam / 4, dUE1) ; - break ; - case 2: // taglio solo la seconda - pCrv2->GetParamAtLength( m_TParams.m_dDiam / 4, dUS2) ; - break ; - case 3: // taglio entrambe - pCrv1->GetParamAtLength( dLen1 - m_TParams.m_dDiam / 4, dUE1) ; - pCrv2->GetParamAtLength( m_TParams.m_dDiam / 4, dUS2) ; - break ; - default: - break; - } - - pCrvH1.Set( GetCurveLine( pCrv1->CopyParamRange( dUS1, dUE1))) ; - pCrvH2.Set( GetCurveLine( pCrv2->CopyParamRange( dUS2, dUE2))) ; - pCrvH1->GetEndPoint( ptS) ; - pCrvH1->GetEndDir( vtS) ; - pCrvH2->GetStartPoint( ptE) ; - pCrvH2->GetStartDir( vtE) ; - if ( ! CalcBoundedSmootedLink( ptS, vtS, ptE, vtE, 0.5, vOffIslands, pCrvTempLink)) - return false ; - } - else { - return false ; - } - - // controllo finale sui raccordi ammissibili ... - if ( pCrvTest->AddCurve( pCrvH1->Clone()) && pCrvTest->AddCurve( pCrvTempLink->Clone()) && pCrvTest->AddCurve( pCrvH2->Clone())) { - //pCrv1->Clear() ; - //pCrv1->AddCurve( Release( pCrvH1)) ; - Point3d pt1, pt2; - pCrvH1->GetStartPoint(pt1); - pCrvH1->GetEndPoint(pt2); - pCrv1->Set(pt1, pt2); - pCrvLink->Clear() ; - //m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCrvTempLink->Clone()); - pCrvLink->AddCurve( pCrvTempLink->Clone()) ; - pCrvH2->GetStartPoint(pt1); - pCrvH2->GetEndPoint(pt2); - pCrv2->Set(pt1, pt2); - //pCrv2->Clear() ; - //pCrv2->AddCurve( pCrvH2->Clone()) ; - - return true ; - } - - return false ; -} - -//---------------------------------------------------------- -bool -Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, double dDepth, double dSafeZ, +Pocketing::OptimizedZigZag( int nPathId, const Vector3d& vtTool, double dDepth, double dSafeZ, Frame3d& frPocket, bool& bOptimizedZigZag, ICRVCOMPOPOVECTOR& vpCrvs) { - // clono la superficie (chunk c-esimo dell'originale) - PtrOwner pSrfPocket( CloneSurfFlatRegion( pSrf)) ; - if ( IsNull( pSrfPocket)) - return false ; - - // recupero la curva ORIGINALE che delimita la svuotatura (questa curva non risente dell'offset fatto dalla superificie creata dopo) - int nCrvId = pSrfPocket->GetLoop( 0, 0)->GetTempProp( 0) ; + // recupero la curva originale che delimita la svuotatura + int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; PtrOwner pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ; if ( IsNull( pCrvPocket)) - return true ; - - // porto la curva nel sistema di riferimento locale + return false ; pCrvPocket->ToLoc( frPocket) ; - - // setto proprietà sulle curve SetCurveAllTempProp( nCrvId, pCrvPocket) ; pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - // sistemo senso antiorario visto dalla direzione di estrusione Vector3d vtPocket; pCrvPocket->GetExtrusion( vtPocket) ; Plane3d plPlane ; double dArea ; @@ -3126,7 +2550,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl // recupero gli id dei lati chiusi INTVECTOR vnInfoClosed ; - for( int i = 0 ; i < pCrvPocket->GetCurveCount() ; i++) { + for( int i = 0 ; i < pCrvPocket->GetCurveCount() ; i ++) { int nProp ; if ( pCrvPocket->GetCurveTempProp( i, nProp) && nProp == 0) vnInfoClosed.push_back( i) ; @@ -3135,21 +2559,21 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl // modifico pCrvPocket per poterla passare a CalcZigZag bool bTwoOpposite ; - Vector3d vtDir ; // direzione principale del segmento più lungo (linea) + Vector3d vtDir ; switch ( nClosedSides) { - case 0 : // 0 lati CHIUSI -> tutti APERTI + case 0 : ZigZagOptimizedNoClosedEdges( pCrvPocket, bOptimizedZigZag, vtDir) ; break ; - case 1 : // 1 lato CHIUSO + case 1 : ZigZagOptimizedOneClosedEdge( pCrvPocket, vnInfoClosed[0], bOptimizedZigZag, vtDir) ; break ; - case 2 : // 2 lati CHIUSI + case 2 : ZigZagOptimizedTwoClosedEdges( pCrvPocket, vnInfoClosed, bOptimizedZigZag, bTwoOpposite, vtDir) ; break ; - case 3 : // 3 lati CHIUSI + case 3 : ZigZagOptimizedThreeClosedEdges( pCrvPocket, vnInfoClosed, bOptimizedZigZag, bTwoOpposite, vtDir) ; break ; - default : // nessuna ottimizzazione... + default : bOptimizedZigZag = false ; break ; } @@ -3165,72 +2589,13 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl if ( nClosedSides == 0) dAng += m_Params.m_dSideAngle ; pCrvPocket->ToGlob( frPocket) ; - - Frame3d frameH( frPocket) ; - Point3d ptCen = frPocket.Orig() ; Vector3d vtExtr = frPocket.VersZ() ; frPocket.Rotate( ptCen, vtExtr, -dAng) ; pCrvPocket->ToLoc( frPocket) ; - // vettore contenente le curve di primo Offset ottimizzate ( bordo esterno Optimized e isole ) - ICRVCOMPOPOVECTOR vFirstOffsets ;; - vFirstOffsets.emplace_back( Release( pCrvPocket)) ; // la curva esterna modificata - - double dTRad = m_TParams.m_dDiam / 2 ; - double dOffs = dTRad + GetOffsR() ; - double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ; - - PtrOwner pSrfPocketClone( CloneSurfFlatRegion( pSrfPocket)) ; - if ( IsNull( pSrfPocketClone)) - return false ; - - if ( ! pSrfPocketClone->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) { // le isole interne vanno Offsettate - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - return false ; - } - - ICRVCOMPOPOVECTOR vCrvAllLoops ; - double dMaxArea = -INFINITO; int nIndex = -1; int p = 0 ; // p è il # di loop totali - - for ( int cu = 0 ; cu < pSrfPocketClone->GetChunkCount(); cu++) { - for ( int l = 0 ; l < pSrfPocketClone->GetLoopCount( cu); l++) { - // inserisco i loops portandoli nel nuovo sistema di riferimento - PtrOwner pCrvLoop( GetCurveComposite( pSrfPocketClone->GetLoop( cu, l))) ; - if ( IsNull( pCrvLoop)) - return false ; - pCrvLoop->ToGlob( frameH) ; - pCrvLoop->ToLoc( frPocket) ; - - double dArea; pCrvLoop->GetAreaXY( dArea) ; - if ( dArea > dMaxArea) { - dMaxArea = dArea ; - nIndex = p ; - } - - vCrvAllLoops.emplace_back( Release( pCrvLoop)) ; - p++ ; - } - } - - for ( int i = 0 ; i < vCrvAllLoops.size() ; i++) { - if ( i != nIndex) { - vFirstOffsets.emplace_back( vCrvAllLoops[i]->Clone()) ; - } - } - - // creo la superficie da svuotare ottimizzata - SurfFlatRegionByContours pSrfMod ; - for ( int i = 0 ; i < vFirstOffsets.size() ; i++) - pSrfMod.AddCurve( vFirstOffsets[i]->Clone()) ; - PtrOwner pSrfZigZag( GetSurfFlatRegion( pSrfMod.GetSurf())) ; - if ( IsNull( pSrfZigZag)) - return false ; - if ( AreOppositeVectorApprox( vtExtr, pSrfZigZag->GetNormVersor())) - pSrfZigZag->Invert() ; - // calcolo il percorso di svuotatura - if ( ! CalcZigZag( pSrfZigZag, vpCrvs)) + if ( ! CalcZigZag( pCrvPocket, vpCrvs)) return false ; // se un lato chiuso @@ -3242,11 +2607,11 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl vpCrvs[0]->GetStartPoint( ptStart) ; Vector3d vtDir ; vpCrvs[0]->GetStartDir( vtDir) ; - Point3d ptTest = ptStart + ( - vtDir) * ( m_TParams.m_dDiam / 2 + dSafeZ) ; + Point3d ptTest = ptStart + ( -vtDir) * ( m_TParams.m_dDiam / 2 + dSafeZ) ; ptTest.ToGlob( frPocket) ; ptTest += - vtTool * dDepth ; double dTestElev ; - // se è nel grezzo provo a ruotare di 90 gradi + // se è nel grezzo provo a ruotare di 90 gradi if ( GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) && dTestElev > EPS_SMALL) { Vector3d vtDirO = vtDir ; vtDirO.Rotate( Z_AX, ( m_Params.m_bInvert ? -90 : 90)) ; @@ -3254,7 +2619,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl ptTestO.ToGlob( frPocket) ; ptTestO += - vtTool * dDepth ; double dTestElevO ; - // se è fuori dal grezzo uso inizio ruotato + // se è fuori dal grezzo uso inizio ruotato if ( ! GetElevation( m_nPhase, ptTestO, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElevO) || dTestElevO < EPS_SMALL) { Point3d ptNewStart = ptStart + vtDirO ; vpCrvs[0]->AddLine( ptNewStart, false) ; @@ -3262,7 +2627,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl } } // se due lati chiusi consecutivi o tre lati chiusi... - else if (( nClosedSides == 2 || nClosedSides == 3) && ! bTwoOpposite) { + else if ( ( nClosedSides == 2 || nClosedSides == 3) && ! bTwoOpposite) { // inverto il percorso vpCrvs[0]->Invert() ; // allungo opportunamente inizio e fine @@ -3290,7 +2655,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl bool Pocketing::ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOptimizedZigZag, Vector3d& vtDir) { - // individuo il segmento di retta più lungo + // individuo il segmento di retta più lungo int nMax = -1 ; double dMaxLen = 0 ; for ( int i = 0 ; i < int( pCrvPocket->GetCurveCount()) ; ++ i) { @@ -3338,7 +2703,7 @@ Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClose pCrv->ExtendStartByLen( 300) ; pCrv->ExtendEndByLen( 300) ; - // sarà la prima curva del percorso + // sarà la prima curva del percorso if ( ! CutCurveWithLine( pCrvPocket, pCrv)) return false ; @@ -3354,9 +2719,8 @@ Pocketing::ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INT // verifico che i lati chiusi siano linee PtrOwner pCrv1( CloneCurveLine( pCrvPocket->GetCurve( vnClosedIds[0]))) ; PtrOwner pCrv2( CloneCurveLine( pCrvPocket->GetCurve( vnClosedIds[1]))) ; - if ( IsNull( pCrv1) || IsNull( pCrv2)) + if ( IsNull( pCrv1) || IsNull( pCrv2)) return true ; - // verifico abbiano direzioni opposte Vector3d vtDir1, vtDir2 ; pCrv1->GetStartDir( vtDir1) ; @@ -3385,7 +2749,7 @@ Pocketing::ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INT pCrv1->SetExtrusion( vtExtr) ; pCrv2->SetExtrusion( vtExtr) ; - // determino la curva chiusa più lunga + // determino la curva chiusa più lunga double dLen1 ; pCrv1->GetLength( dLen1) ; double dLen2 ; pCrv2->GetLength( dLen2) ; @@ -3410,7 +2774,7 @@ Pocketing::ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INT if ( ! CutCurveWithLine( pCrvPocket, pCrv1)) return false ; - // sarà la prima curva del percorso + // sarà la prima curva del percorso pCrv2->SimpleOffset( -dOffs) ; pCrv2->ExtendStartByLen( 300) ; pCrv2->ExtendEndByLen( 300) ; @@ -3498,7 +2862,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I if ( ! CutCurveWithLine( pCrvPocket, pCrv3)) return false ; - // sarà la prima curva del percorso + // sarà la prima curva del percorso pCrv2->SimpleOffset( -dOffs) ; pCrv2->ExtendStartByLen( 300) ; pCrv2->ExtendEndByLen( 300) ; @@ -3514,8 +2878,8 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I Pocketing::ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vector3d& vtMainDir, int nOffsettedEdgesOnY, const INTVECTOR& vnClosedIds) { - // calcolo il side step che verrà utilizzato in CalcZigZag - /*Frame3d frLoc; + // calcolo il side step che verrà utilizzato in CalcZigZag + Frame3d frLoc ; if ( ! frLoc.Set( ORIG, Z_AX, vtMainDir)) return true ; BBox3d b3Loc ; @@ -3532,7 +2896,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I // individuo i lati vicini a quelli closed for ( int i = 0 ; i < ( int)vnClosedIds.size() ; i ++) { - int nNext = vnClosedIds[i] == pCrvPocket->GetCurveCount() - 1 ? 0 : vnClosedIds[i] + 1 ; + int nNext = vnClosedIds[i] == pCrvPocket->GetCurveCount() - 1 ? 0 : vnClosedIds[i] + 1 ; int nPrev = vnClosedIds[i] == 0 ? pCrvPocket->GetCurveCount() - 1 : vnClosedIds[i] - 1 ; pCrvPocket->SetCurveTempProp( nNext, 1, 1) ; pCrvPocket->SetCurveTempProp( nPrev, 1, 1) ; @@ -3540,12 +2904,12 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I // verifico se resteranno aree residue e calcolo eventuale offset per pCrvPocket double dOffs = 0 ; - for (int i = 0; i < pCrvPocket->GetCurveCount(); i++) { + for ( int i = 0 ; i < pCrvPocket->GetCurveCount() ; i ++) { double dOffsTmp = 0 ; double dVal = 0 ; - if ( pCrvPocket->GetCurve( i)->GetType() == CRV_LINE) { + if ( pCrvPocket->GetCurve(i)->GetType() == CRV_LINE) { Vector3d vtDir ; if ( ! pCrvPocket->GetCurve( i)->GetStartDir( vtDir)) return false ; @@ -3556,14 +2920,14 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I pCrvPocket->GetCurve( i)->GetLength( dLen) ; if ( nProp == 1 && dLen > 1000 * EPS_SMALL) { - // gestione speciale se vicino al lato closed + // gestione speciale se vicino al lato closed double dCosAlpha = vtMainDir * vtDir ; - if ( abs( dCosAlpha) > EPS_SMALL && abs( dCosAlpha) < 1 - EPS_SMALL) // se non quasi paralleli o quasi perpendicolari + if ( abs( dCosAlpha) > EPS_SMALL && abs( dCosAlpha) < 1 - EPS_SMALL) dOffsTmp = abs( 0.5 * m_TParams.m_dDiam * dCosAlpha) ; } else { double dSinAlpha = ( vtMainDir ^ vtDir).Len() ; - if ( abs( dSinAlpha) > EPS_SMALL) // se sono quasi perpendicolari + if ( abs( dSinAlpha) > EPS_SMALL) dVal = ( dYSideStep - 0.5 * m_TParams.m_dDiam) / dSinAlpha - 0.5 * m_TParams.m_dDiam ; if ( dVal > EPS_SMALL) { double dCosAlpha = vtMainDir * vtDir ; @@ -3573,9 +2937,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I } if ( dOffsTmp > dOffs) dOffs = dOffsTmp ; - }*/ - - double dOffs = m_TParams.m_dDiam / 2 + 5 * EPS_SMALL; + } if ( dOffs > EPS_SMALL) { // calcolo offset @@ -3591,7 +2953,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I pCrvPocket->Clear() ; pCrvPocket->AddCurve( OffsCrv.GetCurve()) ; } - + return true ; } @@ -3625,429 +2987,305 @@ Pocketing::CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) //---------------------------------------------------------------------------- bool -Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) +Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) { - // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore + // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { + if ( ! LeadInIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false; + return false ; } } // determino numero e affondamento degli step int nStep = 1 ; - nStep = max( 1, static_cast( ceil(dElev / dOkStep))) ; + nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; double dStep = dElev / nStep ; + // calcolo curva offsettata del raggio utensile + sovramateriale double dTRad = 0.5 * m_TParams.m_dDiam ; double dOffs = dTRad + GetOffsR() ; - double dExtra = min( 0.1 * m_TParams.m_dDiam, 1.0) ; - - // copio la regione da svuotare, il Chunk (c)-esimo - PtrOwner pSrfToPock( pSrfPock->Clone()) ; - if ( IsNull( pSrfToPock)) + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( pCompo, - dOffs, ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; + } - // classifico i chunks in modo da creare delle regioni ideali; una regione ideale è formata da un chunk principale - // con tutti gli altri contenuti in esso ( in questo modo ottimizzo i percorsi per i bordi) - typedef vector> SRFFLTVECTOR ; - SRFFLTVECTOR vSrfFlat ; - INTVECTOR vChunksAvailable( pSrfToPock->GetChunkCount(), 1) ; + // ciclo sulle curve risultanti + while ( OffsCrv.GetCurveCount() > 0) { - for ( int c = 0 ; c < pSrfToPock->GetChunkCount() ; c++) { - PtrOwner pSrfIdeal( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfIdeal)) + // recupero la prima curva di offset + PtrOwner pOffs( CreateCurveComposite()) ; + if ( IsNull( pOffs) || ! pOffs->AddCurve( OffsCrv.GetLongerCurve())) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; - if ( vChunksAvailable[c] == 1) { // se Chunk valido... - PtrOwner pCrvExt( GetCurveComposite( pSrfToPock->GetLoop( c, 0))) ; - if ( IsNull( pCrvExt)) - return false ; - pSrfIdeal.Set( pSrfToPock->CloneChunk( c)) ; - vChunksAvailable[c] = -1 ; - for ( int i = 0; i < vChunksAvailable.size(); i++) { - if ( vChunksAvailable[i] == 1) { // se chunk valido... - PtrOwner pCrvExtC( GetCurveComposite( pSrfToPock->GetLoop( i, 0))) ; - if ( IsNull( pCrvExtC)) + } + + // se richiesto, la inverto + if ( m_Params.m_bInvert) + pOffs->Invert() ; + + // sposto l'inizio a metà del tratto più lungo + AdjustContourStart( pOffs) ; + + // verifico archi + VerifyArcs( pOffs) ; + + // coefficiente di riduzione feed di lavorazione di questa curva + double dFeedRid = min( GetSideStep() / m_TParams.m_dDiam, 1.0) ; + + // aggiungo la lavorazione di questa curva + Point3d ptP1 ; + for ( int j = 1 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + int nMaxInd = pOffs->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pOffs->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino inizio attacco + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw) + dStElev = max( dStElev, dStep) ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * dStElev ; + dStElev = 0 ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( dFeedRid * GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; - IntersCurveCurve intCC( *pCrvExtC, *pCrvExt) ; - CRVCVECTOR ccClass ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if ( ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN) { - pSrfIdeal->Add( *pSrfToPock->CloneChunk( i)) ; - vChunksAvailable[i] = -1 ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( dFeedRid * GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità + if ( i == nMaxInd) { + // se ultimo step, uscita e retrazione di collegamento + if ( j == nStep) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } } } } } - if ( pSrfIdeal->GetChunkCount() > 0) { - vSrfFlat.emplace_back( Release( pSrfIdeal)) ; - } } - // === per ogni superificie ideale creo 2 Offsets ===, - // - dOffs con le curve da percorrere all'inizio ( bordo da percorrere, senza mai superarlo) - // - dOffs - dExtra per definire le curve interne della svuotatura ( bordo immaginario per il OneWay ) + // calcolo seconda curva di offset + OffsetCurve OffsCrv2 ; + double dExtra = min( 0.1 * m_TParams.m_dDiam, 1.0) ; + if ( ! OffsCrv2.Make( pCompo, - ( dOffs + dExtra), ICurve::OFF_FILLET)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } - for ( int nIdealSurf = 0 ; nIdealSurf < vSrfFlat.size() ; nIdealSurf++) { + // ciclo sulle curve risultanti + while ( OffsCrv2.GetCurveCount() > 0) { - // === PRIMO OFFSET === - PtrOwner pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIdealSurf])->Clone()) ; - if ( IsNull( pSrfIdeal)) - return false ; - - // per entrate ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfIdeal)) ; - - // effettuo il primo Offset della regione e controllo quanti Chunks ottengo - if ( ! pSrfIdeal->Offset( - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + PtrOwner pOffs2( CreateCurveComposite()) ; + if ( IsNull( pOffs2) || ! pOffs2->AddCurve( OffsCrv2.GetLongerCurve())) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // salvo tutte le curve di Offset in un vettore per poi ordinarle - ICRVCOMPOPOVECTOR vAllCrv ; - for ( int cc = 0 ; cc < pSrfIdeal->GetChunkCount() ; cc++) { - for ( int l = 0 ; l < pSrfIdeal->GetLoopCount( cc) ; l++) { - vAllCrv.emplace_back( GetCurveComposite( pSrfIdeal->GetLoop( cc, l))) ; - } - } - - int nClosestInd = -1 ; int nFlag ; int nFocus = 0 ; - double dDist = INFINITO ; - Point3d ptHelp ; - - // scorro tutte le curve - for ( int i = 0 ; i < vAllCrv.size() ; i++) { - - //se richiesto, la inverto - if ( m_Params.m_bInvert) - vAllCrv[i]->Invert() ; - - // verificare casi ottimizzati per OneWay ? - // ... - - // resetto le proprietà per casi ottimizzati - ResetCurveAllTempProp( vAllCrv[i]) ; - - if ( i == 0) { - // sposto l'inizio a metà del tratto più lungo - AdjustContourStart( vAllCrv[i]) ; - } - else if ( i < vAllCrv.size() - 1) { - // sposto l'inizio della curva più vicina al punto finale precendente - Point3d ptS ; - vAllCrv[i]->GetStartPoint( ptS) ; - - // setto i default delle variabili - if ( ! DistPointCurve( ptS, *vAllCrv[i + 1]).GetMinDistPoint( EPS_SMALL, ptHelp, nFlag)) - return false ; - dDist = INFINITO ; - - for ( int j = i + 1 ; j <= vAllCrv.size() - 1 ; j++) { - - // cerco il punto più vicino della curva - Point3d ptE ; - - if ( ! DistPointCurve( ptS, *vAllCrv[j]).GetMinDistPoint( EPS_SMALL, ptE, nFlag)) - return false ; - - if ( dDist > Dist(ptS, ptE)) { - dDist = Dist( ptS, ptE) ; - nClosestInd = j ; - ptHelp.Set( ptE.x, ptE.y, ptE.z) ; - } - } - - // avendo la curva più vicina ... - if ( nClosestInd != i + 1) { - PtrOwner ptoCCHelp( GetCurveComposite( Release(vAllCrv[i + 1]))); - vAllCrv[i + 1].Set( Release( vAllCrv[nClosestInd])) ; - vAllCrv[nClosestInd].Set(Release( ptoCCHelp)) ; - } - - // cambio il suo punto iniziale ... - double dU ; - Point3d ptNE( ptHelp.x, ptHelp.y, ptHelp.z) ; - if ( ! vAllCrv[i + 1]->GetParamAtPoint( ptNE, dU)) - return false ; - vAllCrv[i + 1]->ChangeStartPoint( dU) ; - - } - - // verifico archi - VerifyArcs( vAllCrv[i]) ; - - PtrOwner pOffs( CreateCurveComposite()); - if ( IsNull( pOffs) || ! pOffs->AddCurve( vAllCrv[i]->Clone())) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - - // coefficiente di riduzione feed di lavorazione di questa curva - double dFeedRid = min(GetSideStep() / m_TParams.m_dDiam, 1.0); - - // aggiungo la lavorazione di questa curva - Point3d ptP1 ; - for ( int j = 1 ; j <= nStep ; ++j) { - // ciclo sulle curve elementari - int nMaxInd = pOffs->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++i) { - // curva corrente - const ICurve* pCrvC = pOffs->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - // aggiungo affondamento - pCurve->Translate( -vtTool * ( dDepth - dElev + j * dStep)) ; - // SE PRIMA ENTITA' - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo - if ( j == 1) { - // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) - return false ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) - dStElev = max( dStElev, dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * dStElev ; - dStElev = 0 ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; - return false ; - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false; - } - } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } - } - } - // elaborazioni sulla curva corrente (aggiungo movimenti dell'utensile : LINEAR o ARC) - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - SetFeed( dFeedRid * GetFeed()) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - SetFeed( dFeedRid * GetFeed()) ; - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // SE ULTIMA ENTITA' - if ( i == nMaxInd) { - // se ultimo step, uscita e retrazione di collegamento - if ( j == nStep) { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - Point3d ptP1 ; - double dEndElev = dElev ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - // aggiungo retrazione - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } - } - } - } - } - } - - // determino il riferimento in base alla svuotatura + // determino il riferimento di base e il box della svuotatura Frame3d frPocket ; - Point3d ptCen ; pSrfIdeal->GetCentroid( ptCen) ; + Point3d ptCen ; pCompo->GetCentroid( ptCen) ; frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate ( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pSrfIdeal->ToLoc( frPocket) ; - BBox3d b3Pocket ; pSrfIdeal->GetLocalBBox( b3Pocket) ; + frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; + pOffs2->ToLoc( frPocket) ; + BBox3d b3Pocket ; + pOffs2->GetLocalBBox( b3Pocket) ; Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; // passi in Y - int nYStep = static_cast( ceil((dDimY + 2 * dExtra) / GetSideStep())) ; + int nYStep = static_cast( ceil( ( dDimY + 2 * dExtra) / GetSideStep())) ; double dYStep = ( nYStep > 0 ? ( dDimY + 2 * dExtra) / nYStep : 0) ; - --nYStep ; + -- nYStep ; // calcolo le linee di svuotatura const double EXP_LEN = 1.0 ; - for ( int j = 1 ; j <= nStep ; ++j) { - for ( int i = 1 ; i <= nYStep ; ++i) { - - // definisco la linea + for ( int j = 1 ; j <= nStep ; ++ j) { + for ( int i = 1 ; i <= nYStep ; ++ i) { + // definisco la linea PtrOwner pLine( CreateCurveLine()) ; Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + ( - dExtra + i * dYStep), ptMin.z + dDimZ) ; - if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { + if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - - // riempio il vettore di segmenti - CRVCVECTOR ccClassSeg ; - pSrfIdeal->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ; - for ( int w = 0 ; w < ccClassSeg.size() ; w++) { - if ( ccClassSeg[w].nClass == CRVC_IN) { - - PtrOwner pCrvSeg( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ; - double duF, dLen ; - // accorcio leggermente il segmento per non toccare la prima curva di Offset - if ( ! pCrvSeg->GetLength( dLen) - || dLen < 2 * dExtra - || ! pCrvSeg->GetParamAtLength( dLen - dExtra, duF) - || ! pCrvSeg->TrimStartAtLen( dExtra) - || ! pCrvSeg->TrimEndAtParam( duF)) - pCrvSeg.Set( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ; - - Point3d ptS, ptE ; - pCrvSeg->GetStartPoint( ptS) ; - pCrvSeg->GetEndPoint( ptE) ; - - // ricavo la curva su cui si trova il punto iniziale - PtrOwner pCrvPtStartOn( CreateCurveComposite()) ; - if ( IsNull( pCrvPtStartOn)) - return false ; - for ( int v = 0; v < pSrfIdeal->GetChunkCount(); v++) { - for ( int b = 0; b < pSrfIdeal->GetLoopCount( v); b++) { - PtrOwner pCrvTest( GetCurveComposite( pSrfIdeal->GetLoop( v, b))) ; - if ( IsNull( pCrvTest)) - return false ; - if ( pCrvTest->IsPointOn( ptS)) { - pCrvPtStartOn.Set( Release( pCrvTest)) ; - v = pSrfIdeal->GetChunkCount() ; - break ; - } - } - } - - // INIZIO - ptS.ToGlob( frPocket) ; - ptS.Translate( - vtTool * (dDepth - dElev + j * dStep)) ; - // determino inizio attacco - Point3d ptP ; - if ( ! CalcLeadInStart( ptS, frPocket.VersX(), vtExtr, nullptr, ptP)) - return false; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = j * dStep ; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev); - if ( bUnderRaw) - dStElev = max( dStElev, j * dStep) ; - dStElev -= ( ptP - ptS) * vtExtr ; - // sempre approccio di collegamento - if ( ! AddLinkApproach( ptP, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable"); - return false; - } - // aggiungo attacco (forzato ad essere lineare) - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs, true)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable"); + // calcolo la classificazione della curva rispetto al contorno esterno offsettato + IntersCurveCurve intCC( *pLine, *pOffs2) ; + CRVCVECTOR ccClass ; + if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + // determino gli intervalli di curva da conservare + Intervals inOk ; + for ( auto& ccOne : ccClass) { + if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M) + inOk.Add( ccOne.dParS, ccOne.dParE) ; + } + // inserisco i tratti validi + double dParS, dParE ; + bool bFound = inOk.GetFirst( dParS, dParE) ; + while ( bFound) { + // calcolo inizio con affondamento + Point3d ptS ; pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, ptS) ; + ptS.ToGlob( frPocket) ; + ptS.Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // determino inizio attacco + Point3d ptP ; + if ( ! CalcLeadInStart( ptS, frPocket.VersX(), vtExtr, nullptr, ptP)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = j * dStep ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw) + dStElev = max( dStElev, j * dStep) ; + dStElev -= ( ptP - ptS) * vtExtr ; + // sempre approccio di collegamento + if ( ! AddLinkApproach( ptP, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs, true)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + // calcolo fine con affondamento + Point3d ptE ; pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, ptE) ; + ptE.ToGlob( frPocket) ; + ptE.Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // movimento al punto finale + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptE) == GDB_ID_NULL) + return false ; + // risalita + Point3d ptQ ; + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, ptQ, dEndElev, true)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // recupero successivo intervallo + bFound = inOk.GetNext( dParS, dParE) ; + // se ultimo movimento di ultima area, aggiungo retrazione globale + if ( j == nStep && i == nYStep && ! bFound && OffsCrv2.GetCurveCount() == 0) { + if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; return false ; } - - ptE.ToGlob( frPocket) ; - ptE.Translate( - vtTool * (dDepth - dElev + j * dStep)) ; - - // movimento al punto finale - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptE) == GDB_ID_NULL) + } + // altrimenti aggiungo retrazione di collegamento + else { + if ( ! AddLinkRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; - - // FINE - Point3d ptQ ; - double dEndElev = dElev ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, ptQ, dEndElev, true)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false; } - - // se ultimo movimento di ultima area, aggiungo retrazione globale - if ( j == nStep && i == nYStep) { - if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; - return false; - } - } - // altrimenti aggiungo retrazione di collegamento - else { - if ( ! AddLinkRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false; - } - } - } } - } } - } return true ; } - //---------------------------------------------------------------------------- bool -Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtStart, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs, BOOLVECTOR vbMidOpen, - PNTVECTOR vPtMidOpen, VCT3DVECTOR vVtMidOut, int nPathId) +Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, bool bMidOpen, + const Point3d& ptMidOpen, const Vector3d& vtMidOut, int nPathId) { // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; @@ -4055,263 +3293,238 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtStar // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // ciclo sui Chunks - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; c++) { - - // copio il chunk - PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) + // ciclo sulle regioni + const int MAX_REGS = 50 ; + int nReg = 0 ; + while ( nReg < MAX_REGS) { + + // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine + PtrOwner pMCrv( CreateCurveComposite()) ; + PtrOwner pRCrv( CreateCurveComposite()) ; + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; return false ; + } - const int MAX_REGS = 50 ; - int nReg = 0 ; - - // porto il Chunk nel sistema di riferimento locale - Point3d ptCen ; pSrfChunk->GetCentroid(ptCen) ; - Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ; - pSrfChunk->ToLoc( frPocket) ; - - while ( nReg < MAX_REGS) { - - // superifice per ingressi ed uscite - PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunk)); - - // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine - PtrOwner pMCrv( CreateCurveComposite()) ; - PtrOwner pRCrv( CreateCurveComposite()) ; - if (IsNull( pMCrv) || IsNull( pRCrv)) { - m_pMchMgr->SetLastError(2411, "Error in Pocketing : toolpath allocation failed"); - return false; + // se lucidatura con epicicli + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL ) { + // verifico che i parametri lucidatura siano sensati + if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; } + // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli + m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; + } - // se lucidatura con epicicli - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // verifico che i parametri lucidatura siano sensati - if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false; + bool bOptimizedTrap = false ; + if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) + return false ; + // se terminate le regioni, esco + if ( pMCrv->GetCurveCount() == 0) + break ; + ++ nReg ; + + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // riporto il diametro dell'utensile al valore originale + m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; + // aggiorno i percorsi di svuotatura con epicicli + if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + } + + // se prima regione e gestione lato aperto ( caso non ottimizzato) + bool bOutStart = ( nReg == 1 && bMidOpen) ; + if ( bOutStart && ! bOptimizedTrap) { + // calcolo il punto fuori + Point3d ptOut = ptMidOpen + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + // verifico che il punto sia veramente fuori dal grezzo + double dStElev ; + bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ; + if ( bOutStart || m_bOpenOutRaw) { + // aggiungo al ritorno l'uscita + if ( pRCrv->GetCurveCount() == 0) { + Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ; + pRCrv->AddPoint( ptStart) ; } - // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli - m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; + pRCrv->AddLine( ptOut, true) ; + // premetto alla spirale la partenza da fuori + pMCrv->AddLine( ptOut, false) ; } + } - bool bOptimizedTrap = false ; - if ( ! CalcSpiral( pSrfChunk, nReg, vPtStart[c], bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) - return false; + // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + } - // se terminate le regioni, esco - if ( pMCrv->GetCurveCount() == 0) - break ; // passo al chunk originale successivo - ++nReg ; + // verifico se ingresso da considerare fuori grezzo anche se dentro + bool bForcedOutStart = ( bMidOpen && m_bOpenOutRaw) ; - // riporto le curve nel sistema di riferimento della svuotatura - if ( ! bOptimizedTrap) { - pMCrv->ToGlob( frPocket) ; - pRCrv->ToGlob( frPocket) ; + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart && ! bForcedOutStart) { + if ( ! LeadInIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; } + } - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // riporto il diametro dell'utensile al valore originale - m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; - // aggiorno i percorsi di svuotatura con epicicli - if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + // determino numero e affondamento degli step + int nStep = 1 ; + nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; + double dStep = dElev / nStep ; + + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->GetCurveCount() - 1 ; + + // ciclo sugli step + Point3d ptP1 ; + for ( int j = 1 ; j <= nStep ; ++ j) { + // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) + pMCrv->Invert() ; + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) return false ; - } - } - - // se prima regione e gestione lato aperto ( caso non ottimizzato) - bool bOutStart = ( nReg == 1 && vbMidOpen[c]); - if ( bOutStart && !bOptimizedTrap) { - // calcolo il punto fuori - Point3d ptOut = vPtMidOpen[c] + vVtMidOut[c] * (0.5 * m_TParams.m_dDiam + dSafeZ); - // verifico che il punto sia veramente fuori dal grezzo - double dStElev; - bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL); - if ( bOutStart || m_bOpenOutRaw) { - // aggiungo al ritorno l'uscita - if (pRCrv->GetCurveCount() == 0) { - Point3d ptStart; pMCrv->GetStartPoint(ptStart); - pRCrv->AddPoint(ptStart); + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino inizio attacco + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) + return false ; + // determino elevazione su inizio attacco (se non trovata, elevazione è step) + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw || ( bOutStart && ! m_bAboveHead)) + dStElev = max( dStElev, dStep) ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * dStElev ; + dStElev = 0 ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } } - pRCrv->AddLine(ptOut, true); - // premetto alla spirale la partenza da fuori - pMCrv->AddLine(ptOut, false); } - } - - // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato - int nOutsideRaw = 0; - if ( bOptimizedTrap) { - AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; - bOutStart = ( nOutsideRaw > 0) ; - } - - // verifico se ingresso da considerare fuori grezzo anche se dentro - bool bForcedOutStart = ( vbMidOpen[c] && m_bOpenOutRaw); - - // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore - if ( m_TParams.m_nType == TT_MILL_NOTIP && !bOutStart && !bForcedOutStart) { - if ( ! LeadInIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false ; - } - } - - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep ; - - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - int nMaxRInd = pRCrv->GetCurveCount() - 1 ; - - // ciclo sugli step - Point3d ptP1 ; - for ( int j = 1; j <= nStep; ++j) { - // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva - if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) - pMCrv->Invert() ; - // ciclo sulle curve elementari - for ( int i = 0 ; i <= nMaxInd ; ++i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; - // aggiungo affondamento - pCurve->Translate( -vtTool * (dDepth - dElev + j * dStep)) ; - // se prima entità - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo - if ( j == 1) { - // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità + if ( i == nMaxInd) { + // se step intermedio, ritorno all'inizio direttamente + if ( j < nStep) { + // se necessario ritorno all'inizio + if ( nMaxRInd >= 0) { + // copio la curva di ritorno + PtrOwner pRet( pRCrv->Clone()) ; + if ( IsNull( pRet)) return false ; - // determino elevazione su inizio attacco (se non trovata, elevazione è step) - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev); - if ( bUnderRaw || ( bOutStart && !m_bAboveHead)) - dStElev = max( dStElev, dStep) ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * dStElev ; - dStElev = 0 ; + // aggiungo affondamento + pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se attacco a scivolo, accorcio della lunghezza dell'attacco + if ( GetLeadInType() == POCKET_LI_GLIDE) { + double dLen ; pRet->GetLength( dLen) ; + if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) + pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang) ; + else + pRet->Clear() ; } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + // emetto + SetFeed( GetFeed()) ; + if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) return false ; - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } } } - // elaborazioni sulla curva corrente - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptP1, dEndElev)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; - } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3); - SetFeed( GetFeed()) ; - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // se ultima entità - if ( i == nMaxInd) { - // se step intermedio, ritorno all'inizio direttamente - if ( j < nStep) { - // se necessario ritorno all'inizio - if ( nMaxRInd >= 0) { - // copio la curva di ritorno - PtrOwner pRet( pRCrv->Clone()) ; - if ( IsNull( pRet)) - return false ; - // aggiungo affondamento - pRet->Translate( -vtTool * (dDepth - dElev + j * dStep)) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco - if ( GetLeadInType() == POCKET_LI_GLIDE) { - double dLen ; pRet->GetLength( dLen) ; - if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) - pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang) ; - else - pRet->Clear() ; - } - // emetto - SetFeed( GetFeed()) ; - if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) - return false ; - } } - // atrimenti ultimo step, uscita e retrazione - else { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - Point3d ptP1 ; - double dEndElev = dElev ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptP1, dEndElev)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - if ( !m_bAboveHead) - dEndElev = max( dEndElev, j * dStep) ; - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; - return false ; - } + if ( ! m_bAboveHead) + dEndElev = max( dEndElev, j * dStep) ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; + return false ; } } } } } } - return true ; } //---------------------------------------------------------------------------- bool -Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtStart, const Vector3d& vtTool, const Vector3d& vtExtr, +Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) { // recupero distanze di sicurezza @@ -4321,233 +3534,211 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtSta double dAppr = m_Params.m_dStartPos ; // ciclo sulle regioni - for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; c++) { - - // copio il chunk - PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ; - if ( IsNull( pSrfChunk)) + const int MAX_REGS = 50 ; + int nReg = 0 ; + while ( nReg < MAX_REGS) { + + // calcolo la spirale dall'interno all'esterno + PtrOwner pMCrv( CreateCurveComposite()) ; + PtrOwner pRCrv( CreateCurveComposite()) ; + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; return false ; + } - // porto il Chunk nel sistema di riferimento locale - Point3d ptCen ; pSrfChunk->GetCentroid( ptCen) ; - Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ; - pSrfChunk->ToLoc( frPocket) ; - - int nReg = 0; - int MAX_REGS = 50 ; - - while ( nReg < MAX_REGS) { - - // superificie per ingressi ed uscite - PtrOwner pSrfLeanInOut(CloneSurfFlatRegion(pSrfChunk)); - - // calcolo la spirale dall'interno all'esterno - PtrOwner pMCrv(CreateCurveComposite()); - PtrOwner pRCrv(CreateCurveComposite()); - if ( IsNull( pMCrv) || IsNull( pRCrv)) { - m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ; + // se lucidatura con epicicli + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL ) { + // verifico che parametri lucidatura siano sensati + if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } + // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli + m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; + } - // se lucidatura con epicicli - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // verifico che parametri lucidatura siano sensati - if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) { - m_pMchMgr->SetLastError(2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli - m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; - } + bool bOptimizedTrap = false ; + if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) + return false ; + // se terminate le regioni, esco + if ( pMCrv->GetCurveCount() == 0) + break ; + ++ nReg ; - bool bOptimizedTrap = false; - if ( ! CalcSpiral( pSrfChunk, nReg, vPtStart[c], bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) + if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { + // riporto il diametro dell'utensile al valore originale + m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; + // aggiorno i percorsi di svuotatura con epicicli + if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; - - // se terminate le regioni, esco - if ( pMCrv->GetCurveCount() == 0) - break ; - ++nReg ; - - // riporto le curve nel sistema di riferimento della svuotatura - pMCrv->ToGlob( frPocket) ; - pRCrv->ToGlob( frPocket) ; - - if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) { - // riporto il diametro dell'utensile al valore originale - m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ; - // aggiorno i percorsi di svuotatura con epicicli - if (!ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } } + } + + // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo + bool bOutStart = false ; + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + } - // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo - bool bOutStart = false ; - int nOutsideRaw = 0 ; - if ( bOptimizedTrap) { - AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; - bOutStart = ( nOutsideRaw > 0) ; + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { + if ( ! LeadInIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; } + } - // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore - if ( m_TParams.m_nType == TT_MILL_NOTIP && !bOutStart) { - if ( ! LeadInIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false ; - } - } + // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) + if ( ! bOptimizedTrap) { + pMCrv->Invert() ; + pRCrv->Invert() ; + } - // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) - if ( ! bOptimizedTrap) { + // determino numero e affondamento degli step + int nStep = 1 ; + nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; + double dStep = dElev / nStep ; + + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->GetCurveCount() - 1 ; + + // ciclo sugli step + Point3d ptP1 ; + for ( int j = 1 ; j <= nStep ; ++ j) { + // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) pMCrv->Invert() ; - pRCrv->Invert() ; - } - - // determino numero e affondamento degli step - int nStep = 1 ; - nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; - double dStep = dElev / nStep; - - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - int nMaxRInd = pRCrv->GetCurveCount() - 1 ; - - // ciclo sugli step - Point3d ptP1 ; - for ( int j = 1 ; j <= nStep ; ++j) { - // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva - if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) - pMCrv->Invert() ; - // ciclo sulle curve elementari - for ( int i = 0 ; i <= nMaxInd ; ++i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino inizio attacco + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; + bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bUnderRaw || ( bOutStart && ! m_bAboveHead)) + dStElev = max( dStElev, dStep) ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( GetLeadInType() == POCKET_LI_ZIGZAG || + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { + ptP1 += vtExtr * dStElev ; + dStElev = 0 ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { + m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; + return false ; + } + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; - // aggiungo affondamento - pCurve->Translate( -vtTool * (dDepth - dElev + j * dStep)) ; - // se prima entità - if ( i == 0) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo - if ( j == 1) { - // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità + if ( i == nMaxInd) { + // se step intermedio + if ( j < nStep) { + // se necessario ritorno all'inizio + if ( nMaxRInd >= 0) { + // copio la curva di ritorno + PtrOwner pRet( pRCrv->Clone()) ; + if ( IsNull( pRet)) return false ; + // aggiungo affondamento + pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se attacco a scivolo, accorcio della lunghezza dell'attacco + if ( GetLeadInType() == POCKET_LI_GLIDE) { + double dLen ; pRet->GetLength( dLen) ; + if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) + pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang) ; + else + pRet->Clear() ; } - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && !m_bAggrBottom && !m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev); - if ( bUnderRaw || ( bOutStart && !m_bAboveHead)) - dStElev = max( dStElev, dStep); - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco - if ( GetLeadInType() == POCKET_LI_ZIGZAG || - GetLeadInType() == POCKET_LI_HELIX || - GetLeadInType() == POCKET_LI_GLIDE) { - ptP1 += vtExtr * dStElev ; - dStElev = 0 ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { - m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; + // emetto + SetFeed( GetFeed()) ; + if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) return false ; - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { - m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; - return false ; - } - } - // altrimenti solo collegamento - else { - SetFeed( GetStartFeed()) ; - GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { - m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; - return false ; - } } } - // elaborazioni sulla curva corrente - if ( pCurve->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCurve) ; - Point3d ptP3 = pLine->GetEnd() ; - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptQ ; + double dEndElev = dElev ; + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptQ, dEndElev)) { + m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; - } - else if ( pCurve->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCurve) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - SetFeed( GetFeed()); - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) - return false ; - } - // se ultima entità - if ( i == nMaxInd) { - // se step intermedio - if ( j < nStep) { - // se necessario ritorno all'inizio - if ( nMaxRInd >= 0) { - // copio la curva di ritorno - PtrOwner pRet( pRCrv->Clone()) ; - if ( IsNull( pRet)) - return false ; - // aggiungo affondamento - pRet->Translate( -vtTool * ( dDepth - dElev + j * dStep)) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco - if ( GetLeadInType() == POCKET_LI_GLIDE) { - double dLen ; pRet->GetLength( dLen) ; - if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) - pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang) ; - else - pRet->Clear() ; - } - // emetto - SetFeed( GetFeed()) ; - if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) - return false ; - } } - // atrimenti ultimo step, uscita e retrazione - else { - // dati fine entità - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita - Point3d ptQ ; - double dEndElev = dElev; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptQ, dEndElev)) { - m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; - return false ; - } - if ( !m_bAboveHead) - dEndElev = max( dEndElev, j * dStep) ; - // aggiungo retrazione - if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; - return false ; - } + if ( ! m_bAboveHead) + dEndElev = max( dEndElev, j * dStep) ; + // aggiungo retrazione + if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; + return false ; } } } @@ -4559,10 +3750,9 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtSta //---------------------------------------------------------------------------- bool -Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int nReg, Point3d ptStart, bool bSplitArcs, +Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv, int nPathId, bool& bOptimizedTrap) { - // inizializzo i risultati pMCrv->Clear() ; pRCrv->Clear() ; @@ -4571,332 +3761,150 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int nReg, Point3d ptStar double dTRad = 0.5 * m_TParams.m_dDiam ; double dOffs = dTRad + GetOffsR() ; - // recupero il versore normale della superificie, ruotandola nel piano XY - PtrOwner pSrfToWork( pSrfPock->Clone()) ; - if ( IsNull( pSrfToWork) || pSrfToWork->GetChunkCount() == 0) - return false; - - // controllo se ho isole per i casi ottimizzati - bool bHasIsland = false ; - for ( int j = 1 ; j < pSrfPock->GetLoopCount( 0) ; j++) { - PtrOwner pCrvBorder( GetCurveComposite( pSrfPock->GetLoop( 0, j))) ; - if( ! IsNull( pCrvBorder)) - bHasIsland = true ; + // se circonferenza, chiamo la funzione specializzata + Point3d ptCen ; Vector3d vtN ; double dRad ; bool bCCW ; + if ( pCompo->IsACircle( 100 * EPS_SMALL, ptCen, vtN, dRad, bCCW)) { + double dIntRad = 0 ; + if ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT && GetLeadInType() == POCKET_LI_HELIX) { + dIntRad = min( 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam), dRad - dOffs) ; + m_dMaxHelixRad = dIntRad ; + } + if ( nReg == 0) + return CalcCircleSpiral( ptCen, vtN, dRad - dOffs, dIntRad, bSplitArcs, pMCrv, pRCrv) ; + else + return true ; } - // se non ho isole allora controllo casi ottimizzati - if ( ! bHasIsland) { - // caso spirale - PtrOwner pCrvBorder( CreateCurveComposite()) ; - pCrvBorder->AddCurve( pSrfPock->GetLoop( 0, 0)->Clone()) ; - Point3d ptCen ; Vector3d vtN ; double dRad ; bool bCCW ; - if ( pCrvBorder->IsACircle( 100 * EPS_SMALL, ptCen, vtN, dRad, bCCW)) { - double dIntRad = 0 ; - if ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT && GetLeadInType() == POCKET_LI_HELIX) { - dIntRad = min( 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam), dRad - dOffs) ; - m_dMaxHelixRad = dIntRad ; - } - return CalcCircleSpiral( ptCen, vtN, dRad - dOffs, dIntRad, bSplitArcs, pMCrv, pRCrv) ; - } - // caso trapezoide - int nCrvId = pSrfPock->GetLoop( 0, 0)->GetTempProp( 0) ; - PtrOwner pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ; - if ( IsNull( pCrvPocket)) - return true ; - SetCurveAllTempProp( nCrvId, pCrvPocket) ; - pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + // recupero la curva originaria della svuotatura (non allargata per lati aperti) per verificare caso trapezoide + int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; + PtrOwner pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ; + if ( IsNull( pCrvPocket)) + return false ; + SetCurveAllTempProp( nCrvId, pCrvPocket) ; + pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - Point3d pt ; Vector3d vtB1, vtL1, vtB2 ; - if ( pCrvPocket->IsATrapezoid( 100 * EPS_SMALL, pt, vtB1, vtL1, vtB2)) { - Vector3d vtDir( vtB1), vtOtherDir( vtL1) ; - // se parallelogramma scelgo come base i lati lunghi - Vector3d vtL2( - vtB1 + vtL1 + vtB2) ; - if ( AreSameOrOppositeVectorApprox( vtL1, vtL2)) { - if ( vtL1.Len() > vtB1.Len()) - swap( vtDir, vtOtherDir) ; - } - vtDir.Normalize(); - Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir); - double dPocketSize = vtOrtho.Len() ; - if ( dPocketSize < m_TParams.m_dDiam + EPS_SMALL) { - CalcTrapezoidSpiral( pCrvPocket, vtDir, dPocketSize, pMCrv, pRCrv, bOptimizedTrap); - ModifyCurveToSmooted( pCrvPocket, 0.002, 0.002) ; + Point3d pt ; + Vector3d vtB1, vtL1, vtB2 ; + if ( pCrvPocket->IsATrapezoid( 100 * EPS_SMALL, pt, vtB1, vtL1, vtB2)) { + Vector3d vtDir( vtB1), vtOtherDir( vtL1) ; + // se parallelogramma scelgo come base i lati lunghi + Vector3d vtL2( -vtB1 + vtL1 + vtB2) ; + if ( AreSameOrOppositeVectorApprox( vtL1, vtL2)) { + if ( vtL1.Len() > vtB1.Len()) + swap( vtDir, vtOtherDir) ; + } + vtDir.Normalize() ; + Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ; + double dPocketSize = vtOrtho.Len() ; + if ( dPocketSize < m_TParams.m_dDiam + EPS_SMALL) { + if ( nReg == 0) { + CalcTrapezoidSpiral( pCrvPocket, vtDir, dPocketSize, pMCrv, pRCrv, bOptimizedTrap) ; if ( bOptimizedTrap) return true ; } + else + return true ; } - } // ciclo di offset verso l'interno const int MAX_ITER = 1000 ; int nIter = 0 ; - ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset - ICRVCOMPOPOVECTOR vOffsFirstCurve ; // curve di primo offset - - PtrOwner pSrfAct( CloneSurfFlatRegion( pSrfToWork)) ; // regione attuale - PtrOwner pSrfPrec( CloneSurfFlatRegion( pSrfToWork)) ; // regione precedente - if( IsNull( pSrfAct) || IsNull( pSrfPrec) || pSrfAct->GetChunkCount() == 0 || pSrfPrec->GetChunkCount() == 0) - return false ; - PtrOwner pCutRegion( CreateSurfFlatRegion()) ; // regione lavorata dall'utensile - + ICURVEPOVECTOR vOffs ; + ICURVEPOVECTOR vCrvStack ; + DBLVECTOR vRadStack ; + PtrOwner pOffs ; + double dCurrRad = GetCurveRadius( pCompo) ; while ( nIter < MAX_ITER) { - // salvo la regione - pSrfPrec.Set( pSrfAct->Clone()) ; - // calcolo offset della flatRegion - if ( ! pSrfAct->Offset( - dOffs, ICurve::OFF_FILLET)) + // calcolo + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( ( nIter == 0 ? (ICurve*) pCompo : pOffs), - dOffs, ICurve::OFF_FILLET) || + ( nIter == 0 && nReg == 0 && OffsCrv.GetCurveCount() == 0)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; - - // estraggo il contorno della FlatRegion (ciclo i Chunks e prendo i rispettivi Loops) - if ( nIter == 0) { - PtrOwner pSrfChunknReg( pSrfAct->CloneChunk( nReg)) ; - if ( IsNull( pSrfChunknReg)) // se supero i chunk ottenuti - return true ; - pSrfAct.Set( Release( pSrfChunknReg)) ; } - - int nChunks = pSrfAct->GetChunkCount(); - - for ( int i = 0 ; i < nChunks; i++ ) { - // per ogni chunk... - int nLoops = pSrfAct->GetLoopCount( i) ; - for ( int j = 0 ; j < nLoops ; j++ ) { - // per ogni loop... - PtrOwner ptoCCBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ; - if ( j > 0 ) // inverto l'orientamento delle curve interne (offset delle isole trovate) - ptoCCBorder->Invert() ; - // controllo quali regioni di Offset possono essere sostituite - bool bInsert = true ; - - ICurveArc* pCrvToolShape( CreateCurveArc()) ; // superifice di ingombro del tool - if ( pCrvToolShape == nullptr) - return false ; - - // prendo il centroide dell'Offset - Point3d ptC ; - ptoCCBorder->GetCentroid( ptC) ; - - // creo la curva che rappresenta il mio Tool centrata nel centroide dell'Offset - pCrvToolShape->SetXY( ptC, m_TParams.m_dDiam / 2 + 5 * EPS_SMALL) ; - - // guardo se l'Offset è contenuto nella curva del Tool - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *ptoCCBorder, *pCrvToolShape) ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - - if ( ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN && vOffs.size() > 0) - bInsert = false ; - - if( bInsert) - vOffs.emplace_back( Release( ptoCCBorder)) ; - - PtrOwner ptoCCExtBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ; - if ( nIter == 0 ) { // salvo il bordo per i link (non invertiti) - vOffsFirstCurve.emplace_back( Release( ptoCCExtBorder)) ; - } + // se primo offset e richiesta regione oltre il massimo, esco + if ( nIter == 0 && nReg >= OffsCrv.GetCurveCount()) + return true ; + // recupero le curve di offset e le metto sullo stack (se primo offset solo quella voluta) + int nCount = 0 ; + ICurve* pCrv = OffsCrv.GetLongerCurve() ; + while ( pCrv != nullptr) { + if ( nIter != 0 || nReg == nCount) { + vCrvStack.emplace_back( pCrv) ; + vRadStack.emplace_back( dCurrRad) ; + if ( nIter == 0) + break ; } + else + delete( pCrv) ; + pCrv = OffsCrv.GetCurve() ; + ++ nCount ; } - + // recupero la prossima curva di offset + PtrOwner pNextOffs ; + if ( ! vCrvStack.empty()) { + pNextOffs.Set( Release( vCrvStack.back())) ; + vCrvStack.pop_back() ; + dCurrRad = vRadStack.back() ; + vRadStack.pop_back() ; + } + double dRad = GetCurveRadius( pNextOffs) ; + bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ; bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ; - - if ( nChunks > 0) { + // se completato step di offset, accodo la curva offsettata al percorso di lavoro + if ( ! IsNull( pOffs) && ( bNextOk || bSmallRad)) { + // inserisco l'offset nel vettore + vOffs.emplace_back( Release( pOffs)) ; + } + // se offset va bene + if ( bNextOk) { + // sistemo per prossimo step + dCurrRad = dRad ; + pOffs.Set( Release( pNextOffs)) ; + // nuovo valore pari allo step dOffs = GetSideStep() ; } + // se altrimenti riducibile, provo con offset ridotto al raggio utensile else if ( ! bSmallRad) { - pSrfAct.Set( Release( pSrfPrec)) ; - dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad ) ; - } - else + // nuovo valore pari al raggio + dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ; + } + // altrimenti esco + else break ; - + // incremento contatore iterazioni ++ nIter ; - } + } - // se non ho trovato curve di Offset allora esco - if ( vOffs.size() == 0) - return true ; - - // cambio il punto iniziale della prima Curva di Offset - Point3d ptNewStart ; - if ( vOffs[0]->IsPointOn( ptStart)) { - double duS ; - vOffs[0]->GetParamAtPoint( ptStart, duS) ; - vOffs[0]->ChangeStartPoint( duS) ; - } - else { // se non dovesse essere sulla curva, allora cerco il più vicino - int nFlag ; - if ( DistPointCurve( ptStart, *vOffs[0]).GetMinDistPoint( EPS_SMALL, ptNewStart, nFlag)) { - double duS ; - vOffs[0]->GetParamAtPoint( ptNewStart, duS) ; - vOffs[0]->ChangeStartPoint( duS) ; - } - } - - // smusso le curve di offset ( ad eccezione della prima) - ICRVCOMPOPOVECTOR vOffsClosedCurves( vOffs.size()) ; // vettore con tutte le curve di Offset Chiuse - - for ( int i = 0; i < vOffs.size(); i++ ) { - if( i != 0) - ModifyCurveToSmooted( vOffs[i], 0.01, 0.01) ; - vOffs[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - vOffsClosedCurves[i].Set( vOffs[i]->Clone()) ; - } - - for ( int i = 0 ; i < vOffsFirstCurve.size() ; i++ ) { - if( i != 0 ) - ModifyCurveToSmooted( vOffsFirstCurve[i], 0.01, 0.01) ; - vOffsFirstCurve[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - } - - // setto il punto iniziale della svuotatura - double dNewUS ; - vOffs[0]->GetParamAtPoint( ptNewStart, dNewUS); - vOffs[0]->ChangeStartPoint( dNewUS) ; - - // riordino le curve cambiando il loro punto di inizio e creando poi i collegamenti - int nClosestInd = -1 ; int nFlag ; int nFocus = 0 ; - double dDist = INFINITO ; - Point3d ptHelp ; + // calcolo i collegamenti ICURVEPOVECTOR vLinks( vOffs.size()) ; - - for ( int i = 0 ; i < vOffs.size() - 1; i++) { - - Point3d ptS ; - if ( ! vOffs[i]->GetStartPoint( ptS)) - return false ; - - // setto i default delle variabili - if ( ! DistPointCurve( ptS, *vOffs[i+1]).GetMinDistPoint( EPS_SMALL, ptHelp, nFlag)) - return false ; - dDist = INFINITO ; - - for ( int j = i + 1 ; j <= vOffs.size() - 1; j++) { - // cerco il punto più vicino della curva - Point3d ptE ; - - if ( ! DistPointCurve( ptS, *vOffs[j]).GetMinDistPoint( EPS_SMALL, ptE, nFlag)) - return false ; - - if ( dDist > Dist( ptS, ptE) ) { - dDist = Dist( ptS, ptE) ; - nClosestInd = j ; - ptHelp.Set( ptE.x, ptE.y, ptE.z) ; - } - } - // avendo la curva più vicina ... - - // 1) scambio la curva i con la curva nClosestInd - if ( nClosestInd != i + 1) { - PtrOwner ptoCCHelp( GetCurveComposite( Release( vOffs[i + 1]))) ; - vOffs[i + 1].Set( Release( vOffs[nClosestInd])) ; - vOffs[nClosestInd].Set( Release( ptoCCHelp)) ; - } - - // 2) cambio il suo punto iniziale ... - double dU ; - Point3d ptNE( ptHelp.x, ptHelp.y, ptHelp.z) ; - if ( ! vOffs[i + 1]->GetParamAtPoint( ptNE, dU)) - return false ; - vOffs[i + 1]->ChangeStartPoint( dU) ; - - // 2.1) Accorcio la curva per velocizzare ... - if( i == 0 ) { - PtrOwner pCrvExtraOff0( CreateCurveComposite()) ; - if ( IsNull( pCrvExtraOff0)) - return false ; - double dUExtra0 ; - vOffs[0]->GetParamAtLength( m_TParams.m_dDiam/4, dUExtra0) ; - pCrvExtraOff0->AddCurve( GetCurve( vOffs[0]->CopyParamRange( 0, dUExtra0))) ; - //vOffs[0]->AddCurve( Release( pCrvExtraOff0)) ; - PtrOwner pCrvExtraOff1( CreateCurveComposite()) ; - if ( IsNull( pCrvExtraOff1)) - return false ; - double dUExtra1, dLen1, duS, duE ; - if( vOffs.size() > 0) { - vOffs[1]->GetLength( dLen1) ; - if ( dLen1 > m_TParams.m_dDiam/4) { - vOffs[1]->GetParamAtLength( dLen1 - m_TParams.m_dDiam / 4, dUExtra1) ; - vOffs[1]->GetDomain( duS, duE) ; - pCrvExtraOff1->AddCurve( GetCurve( vOffs[1]->CopyParamRange( dUExtra1, duE))) ; - } - - PtrOwner pCrvLink( CreateCurveComposite()) ; - Vector3d vS, vE ; - if ( ! pCrvExtraOff0->GetEndDir( vS) - || ! pCrvExtraOff0->GetEndPoint( ptS) - || ! pCrvExtraOff1->GetStartDir( vE) - || ! pCrvExtraOff1->GetStartPoint( ptNE)) - return false ; - if ( CalcBoundedLink( ptS, ptNE, vOffsFirstCurve, pCrvLink)) { - PtrOwner pCrvFirstLink( Release( pCrvExtraOff0)) ; - pCrvFirstLink->AddCurve( Release( pCrvLink)) ; - pCrvFirstLink->AddCurve( Release( pCrvExtraOff1)) ; - ModifyCurveToSmooted( pCrvFirstLink, 0.025, 0.025) ; - vLinks[1].Set( Release( pCrvFirstLink)) ; - } - } - else { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - - } + for ( int i = 1 ; i < int( vOffs.size()) ; ++ i) { + // punti di inizio e fine + Point3d ptStart ; + vOffs[i-1]->GetEndPoint( ptStart) ; + Point3d ptEnd ; + vOffs[i]->GetStartPoint( ptEnd) ; + // calcolo il collegamento (garantendo che non esca dalla svuotatura) + PtrOwner pCrvLink( CreateCurveComposite()) ; + if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) + vLinks[i].Set( Release( pCrvLink)) ; else { - double dUNS, dUNE, dUNEE, dLen ; - PtrOwner pCrvTest( CreateCurveComposite()) ; - PtrOwner pOff_i0(CloneCurveComposite( vOffs[i])) ; - PtrOwner pOff_i1(CloneCurveComposite( vOffs[i + 1])) ; - if ( ! CutCurveToConnect( vOffs[i], vOffs[i+1], vOffsClosedCurves, vOffsFirstCurve, pCrvTest)) { - PtrOwner pCrvLink( CreateCurveComposite()) ; - Vector3d vS, vE ; - vOffs[i].Set( Release( pOff_i0)) ; vOffs[i+1].Set( Release(pOff_i1)) ; - if ( ! vOffs[i]->GetStartDir( vS) || ! vOffs[i+1]->GetStartDir( vE)) - return false ; - if ( CalcBoundedSmootedLink( ptS, vS, ptNE, vE, 0.5, vOffsFirstCurve, pCrvLink)) - vLinks[i + 1].Set( Release( pCrvLink)) ; - else { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; - return false ; - } - continue ; - } - - if ( ! pCrvTest->GetStartPoint( ptS) - || ! pCrvTest->GetEndPoint( ptNE) - || ! vOffs[i]->GetParamAtPoint( ptS, dUNS) - || ! vOffs[i+1]->GetParamAtPoint( ptNE, dUNE) ) - return false ; - - vOffs[i+1]->ChangeStartPoint( dUNE) ; - PtrOwner pCrvNewOffS( GetCurveComposite( vOffs[i]->CopyParamRange( 0, dUNS))) ; - vOffs[i]->Clear() ; - vOffs[i].Set( Release( pCrvNewOffS)) ; - vLinks[i + 1].Set( Release( pCrvTest)) ; - } - } - - // 3) controllo eventuali parti non svuotate... - PtrOwner pSrfToCut( CreateSurfFlatRegion()) ; - if ( GetUnclearedRegion( vOffsFirstCurve, vOffs, vLinks, pSrfToCut)) { - // 4) Modifico i percorsi - if ( ! RemoveExtraParts( pSrfToCut, vOffs, vOffsClosedCurves, vOffsFirstCurve, vLinks)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } } // calcolo il percorso di ritorno if ( vOffs.size() >= 2) { - - pRCrv->Clear() ; - // punto inziale e finale | vettore iniziale e finale - Point3d ptStart ; vOffs.back()->GetEndPoint( ptStart) ; - Point3d ptEnd ; vOffs.front()->GetStartPoint( ptEnd) ; - Vector3d vtStart ; vOffs.back()->GetEndDir( vtStart) ; - Vector3d vtEnd ; vOffs.front()->GetStartDir( vtEnd) ; - + // punti di inizio e fine + Point3d ptStart ; + vOffs.back()->GetEndPoint( ptStart) ; + Point3d ptEnd ; + vOffs.front()->GetStartPoint( ptEnd) ; // calcolo il ritorno (garantendo che non esca dalla svuotatura) PtrOwner pCrvLink( CreateCurveComposite()) ; - if ( CalcBoundedSmootedLink( ptStart, vtStart, ptEnd, vtEnd, 0.5, vOffsFirstCurve, pCrvLink)) { + if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) { pRCrv->AddCurve( Release( pCrvLink)) ; pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; // se necessario, approssimo archi con rette @@ -4912,16 +3920,14 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int nReg, Point3d ptStar } } - // creo il percorso di lavoro a partire dalla raccolta degli offset e dei collegamenti for ( int i = 0 ; i < int( vOffs.size()) ; ++ i) { // se collegamento da aggiungere if ( ! IsNull( vLinks[i])) { int nCrvsCount0 = pMCrv->GetCurveCount() ; // accodo nel percorso di lavorazione - if ( ! pMCrv->AddCurve( vLinks[i]->Clone())) - return false ; - // nel caso di lucidatura setto proprietà alle curve di collegamento per poterle identificare + pMCrv->AddCurve( Release( vLinks[i])) ; + // nel caso di lucidatura setto proprietà alle curve di collegamento per poterle identificare if ( m_TParams.m_nType == TT_MILL_POLISHING) { for ( int j = nCrvsCount0 ; j < pMCrv->GetCurveCount() ; j ++) pMCrv->SetCurveTempProp( j, LINK_CURVE_PROP) ; @@ -4931,7 +3937,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int nReg, Point3d ptStar if ( m_Params.m_bInvert) vOffs[i]->Invert() ; // aggiungo la curva - pMCrv->AddCurve( vOffs[i]->Clone()) ; + pMCrv->AddCurve( Release( vOffs[i])) ; } // verifico il percorso di lavoro @@ -4949,1590 +3955,79 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int nReg, Point3d ptStar // setto estrusione Vector3d vtExtr ; - if( vOffs.size() > 0) - if ( vOffs[0]->GetExtrusion( vtExtr)) - pMCrv->SetExtrusion( vtExtr) ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::ModifyCurveToSmooted( ICurveComposite* pCrv, double dRightPer, double dLeftPer) { - - // controllo parametri - if ( pCrv == nullptr) - return false ; - - ICURVEPOVECTOR vCrvStepsToFill; // vettore delle Curve da raccordare (curve della composita) - ICURVEPOVECTOR vCrvArcs ; // vettore contenente gli Archi (tra le curve della composita) - INTVECTOR vArcsToJump ; // vettore di indici per gli archi saltati (nel caso non si riesca a raccordare ...) - - // se nella composita ho meno di due curve allora non c'è nulla da raccordare - const ICurve* pMyCrv = pCrv->GetFirstCurve() ; - while ( pMyCrv != nullptr) { - vCrvStepsToFill.emplace_back( pMyCrv->Clone()) ; - pMyCrv = pCrv->GetNextCurve() ; - } - if ( vCrvStepsToFill.size() < 2) - return false ; - - // controllo se la curva è chiusa (nel caso inserisco nel vettore la prima curva due volte, all'inizio e alla fine) - if ( pCrv->IsClosed()) { - const ICurve* pMyCrvFirst = pCrv->GetFirstCurve() ; - vCrvStepsToFill.emplace_back( pMyCrvFirst->Clone()) ; - } - - double dUE_ref, dUS_ref, dRadius, dPar1, dPar2, dULast; - - // riempio il vettore degli archi, scorro tutte le curve da raccordare ( la i-esima e la (i+1)-esima ) - for ( int i = 0; i < vCrvStepsToFill.size() - 1; i++) { - - // controllo che le curve non siano già tangenti - Vector3d vtS, vtE ; - if ( ! vCrvStepsToFill[i]->GetEndDir( vtS) || ! vCrvStepsToFill[i+1]->GetStartDir( vtE)) - continue ; - if ( AreSameVectorApprox( vtS, vtE)) { - vCrvArcs.emplace_back( CreateCurveComposite()) ; // arco nullo - vArcsToJump.push_back( i) ; // da scartare - continue ; - } - - // cerco i paramentri al dRightPer% e dLeftPer% della lunghezza della prima e della seconda curva ( per raccordarli ) - double dU_cm_S = 0 ; double dULast1 = 1; double dULast2 = 1; - - vCrvStepsToFill[i]->GetDomain( dU_cm_S, dULast1) ; - dUE_ref = ( 1 - dRightPer) * dULast1 ; - - vCrvStepsToFill[i+1]->GetDomain( dU_cm_S, dULast2) ; - dUS_ref = dLeftPer * dULast2 ; - - // prendo i punti sulle due curve rispetto a tali parametri - Point3d ptS, ptE ; - if ( ! vCrvStepsToFill[i]->GetPointD1D2( dUE_ref, ICurve::FROM_PLUS, ptS) - || ! vCrvStepsToFill[i+1]->GetPointD1D2( dUS_ref, ICurve::FROM_MINUS, ptE)) - return false ; - - dRadius = Dist( ptS, ptE) ; // uso come raggio la distanza tra i due punti - - int nMaxTestForArcs = 3 ; // tentativi per creare l'arco - int nIterForArcs = 0 ; - bool IntersBTWArcs = false ; - - // creo l'arco di raccordo - PtrOwner pCrvArc( CreateFillet( *vCrvStepsToFill[i]->Clone(), ptS, *vCrvStepsToFill[i+1]->Clone(), ptE, Z_AX, dRadius, dPar1, dPar2)) ; - - // controllo che l'arco creato non sia troppo piccolo - double dArcLen ; - if ( pCrvArc != nullptr && (! pCrvArc->GetLength( dArcLen) || dArcLen < 5 * EPS_SMALL)) { - vCrvArcs.emplace_back( Release( pCrvArc)) ; // arco nullo - vArcsToJump.push_back( i) ; // da scartare - continue ; - } - - if ( i != 0 && vArcsToJump[i-1] == -1 && pCrvArc != nullptr) { // dal secondo arco in poi controllo che non ci siano intersezioni tra essi - IntersCurveCurve intCCH( *pCrvArc, *vCrvArcs[i-1]) ; - if( intCCH.GetIntersCount() > 0 ) - IntersBTWArcs = true ; - } - - // se ho intersezioni tra archi o l'arco creato non è valido, allora provo altre nMaxTestForArcs volte a ricrearlo avvicinando i punti - while (( pCrvArc == nullptr || IntersBTWArcs) && nIterForArcs < nMaxTestForArcs) { - - dUE_ref = ( dULast1 + dUE_ref ) * 0.5 ; - dUS_ref = dUS_ref * 0.5 ; - - if ( ! vCrvStepsToFill[i]->GetPointD1D2( dUE_ref, ICurve::FROM_PLUS, ptS) - || ! vCrvStepsToFill[i+1]->GetPointD1D2( dUS_ref, ICurve::FROM_MINUS, ptE)) - return false ; - - dRadius = Dist( ptS, ptE) ; - - pCrvArc.Set( CreateFillet( *vCrvStepsToFill[i]->Clone(), ptS, *vCrvStepsToFill[i+1]->Clone(), ptE, Z_AX, dRadius, dPar1, dPar2)) ; - nIterForArcs++ ; - - IntersBTWArcs = false ; - if ( i != 0 && vArcsToJump[i-1] == -1 && pCrvArc != nullptr) { // dal secondo arco in poi controllo che non ci siano intersezioni tra essi - IntersCurveCurve intCCH( *pCrvArc, *vCrvArcs[i-1]) ; - if ( intCCH.GetIntersCount() > 0) - IntersBTWArcs = true ; - } - - } - if ( pCrvArc == nullptr) { // se ancora non riesco... salto l'arco - vCrvArcs.emplace_back( Release( pCrvArc)) ; // arco nullo - vArcsToJump.push_back( i) ; // da scartare - continue ; - } - - // se ho creato l'arco lo memorizzo - vCrvArcs.emplace_back( Release( pCrvArc)) ; // arco valido - vArcsToJump.push_back( -1) ; // da considerare - } - - // creo la curva che restituirò - PtrOwner pCrvCO_temp( CreateCurveComposite()) ; - if ( pCrvCO_temp == nullptr) - return false ; - Point3d ptArcHelp, ptFirstPoint ; - - // unisco la curva i-esima con l'arco i-esimo (non guardo l'ultima curva nel vettore, controllo dopo il caso di curva chiusa) - for ( int i = 0 ; i < vCrvStepsToFill.size() -1 ; i++) { - - if ( vArcsToJump[i] == -1) { // se esiste l'arco ... - Point3d ptArcS, ptArcE ; - if ( ! vCrvArcs[i]->GetStartPoint( ptArcS) - || ! vCrvArcs[i]->GetEndPoint( ptArcE) - || ! vCrvStepsToFill[i]->GetParamAtPoint( ptArcS, dUE_ref) - || ! vCrvStepsToFill[i+1]->GetParamAtPoint( ptArcE, dUS_ref)) - return false ; - - if ( i == 0) { // ... e sono nella prima iterazione ... - if ( ! pCrv->IsClosed()) { // ... e se la curva è aperta -> la inserisco nel nuovo percorso - if ( ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[0]->CopyParamRange( 0, dUE_ref)))) - return false ; - } - ptFirstPoint = ptArcS ; - // ... e se la curva è chiusa -> non la inserisco nel nuovo percorso - } - else { // ... e non sono nella prima iterazione (non ha importanza se la curva è chiusa o aperta...) - if ( ! vCrvStepsToFill[i]->GetParamAtPoint( ptArcHelp, dUS_ref) - || ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[i]->CopyParamRange( dUS_ref, dUE_ref)))) - return false ; - // aggiungo la curva 'tagliata per il raccordo' - } - - if ( ! pCrvCO_temp->AddCurve( vCrvArcs[i]->Clone())) // aggiungo l'arco di raccordo - return false ; - ptArcHelp = ptArcE ; - } - else { // se non esiste l'arco ... - if ( i == 0 ) { // e sono nella prima iterazione... - if ( ! vCrvStepsToFill[0]->GetEndPoint( ptArcHelp)) - return false ; - - if ( ! pCrv->IsClosed()) { // ...e se aperta // aggiungo la prima curva per intero - if ( ! vCrvStepsToFill[0]->GetParamAtPoint( ptArcHelp, dUE_ref) - || ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[0]->CopyParamRange( 0, dUE_ref)))) - return false ; - } - ptFirstPoint = ptArcHelp ; - } - else { // ... e non sono nella prima iterazione (non ha importanza se la curva è chiusa o aperta...) - double dUS_cm ; - if ( ! vCrvStepsToFill[i]->GetParamAtPoint( ptArcHelp, dUS_ref) - || ! vCrvStepsToFill[i]->GetDomain( dUS_cm, dUE_ref) - || ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[i]->CopyParamRange( dUS_ref, dUE_ref))) - || ! vCrvStepsToFill[i]->GetEndPoint( ptArcHelp)) - return false ; - } - } - - } - - // ultima curva... - if ( pCrv->IsClosed()) { // se curva chiusa... - if ( ! vCrvStepsToFill[0]->GetParamAtPoint( ptArcHelp, dUS_ref) - || ! vCrvStepsToFill[0]->GetParamAtPoint( ptFirstPoint, dUE_ref) - || ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[0]->CopyParamRange( dUS_ref, dUE_ref)))) - return false ; - } - else { // se curva aperta... ( non ha importanza l'esistenza o meno degli archi...) - double dUS_cm ; - if ( ! vCrvStepsToFill[vCrvStepsToFill.size() - 1]->GetParamAtPoint( ptArcHelp, dUS_ref) - || ! vCrvStepsToFill[vCrvStepsToFill.size() - 1]->GetDomain( dUS_cm, dUE_ref) - || ! pCrvCO_temp->AddCurve( GetCurve( vCrvStepsToFill[vCrvStepsToFill.size() - 1]->CopyParamRange( dUS_ref, dUE_ref)))) - return false ; - } - - // ripristino il punto inziale se la curva è chiusa - double dNewDU ; - if ( ! pCrv->IsClosed()) { - if( ! pCrvCO_temp->GetParamAtPoint( ptArcHelp, dNewDU)) - return false ; - pCrvCO_temp->ChangeStartPoint( dNewDU) ; - } - - pCrv->Clear() ; - pCrv->AddCurve( Release( pCrvCO_temp)) ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, ICRVCOMPOPOVECTOR& vOffsCL, - ICRVCOMPOPOVECTOR& vFirstOffset, ICurveComposite* pCrvLink, double dLenPercS, double dLenPercE, int nMaxIter) { - - // controllo i parametri - if ( pCrvS == nullptr || pCrvE == nullptr ) - return false ; - pCrvLink->Clear() ; - - PtrOwner ptCrvFinal( CreateCurveComposite()) ; - if ( ptCrvFinal == nullptr) - return false ; - - // Prendo i punti, i vettori tangenti e i parametri di essi per le curve - Point3d ptSS, ptSE, ptES, ptEE ; Vector3d vS, vE; double dUSS, dUSE, dUES, dUEE, dLenS, dLenE ; - dUSS = 0; dUSE = 0; - - pCrvS->GetEndPoint( ptSE) ; - pCrvS->GetStartPoint( ptSS); - pCrvE->GetStartPoint( ptES); - pCrvE->GetEndPoint( ptEE) ; - pCrvS->GetEndDir( vS) ; - pCrvE->GetStartDir( vE) ; - pCrvS->GetDomain( dUSS, dUSE) ; - pCrvE->GetDomain( dUES, dUEE) ; - pCrvS->GetLength( dLenS) ; - pCrvE->GetLength( dLenE) ; - - // se ho una curva di primo Offset allora non devo accorciarla ... - bool bCut = true ; - for ( int i = 0 ; i < vFirstOffset.size() ; i++ ) { - if ( vFirstOffset[i]->IsPointOn( ptSS) && vFirstOffset[i]->IsPointOn( ptSE)) - dLenPercS = 0 ; - if ( vFirstOffset[i]->IsPointOn( ptES) && vFirstOffset[i]->IsPointOn( ptEE)) - dLenPercE = 0 ; - } - - - double dLStepS = dLenPercS * dLenS ; - double dLStepE = dLenPercE * dLenE ; - dLenE = 0 ; - - // calcolo i possibili BiArchi tra le due curve - int nIter = 0; - - while ( nIter < nMaxIter) { - - // calcolo il BiArco - PtrOwner ptBiArc( CreateCurveComposite()) ; - if ( ! CalcBoundedSmootedLink( ptSE, vS, ptES, vE, 0.5, vFirstOffset, ptBiArc) - || ptBiArc->GetCurveCount() == 0) - return false ; - - ptCrvFinal->Clear() ; - ptCrvFinal.Set( ptBiArc->Clone()) ; - - if ( dLenPercE == 0 && dLenPercS == 0 ) - break ; - - // se il BiArco creato interseca le altre curve di Offset allora mi fermo... - bool bInterr = false ; - for ( int i = 0 ; i < vOffsCL.size() && ! bInterr ; i++) { - if ( vOffsCL[i]->IsPointOn( ptSE) || vOffsCL[i]->IsPointOn( ptES)) - continue ; - - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *ptBiArc, *vOffsCL[i]) ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if ( ccClass.size() > 1) // se intersezione - bInterr = true ; - } - if ( bInterr) - break ; // così come ultimo arco ho quello precedente (valido) - - // se ho trovato un BiArco valido, allora accorcio le due curve di Offset - dLenS -= dLStepS ; - dLenE += dLStepE ; - - if ( ! pCrvS->GetParamAtLength( dLenS, dUSE) - || ! pCrvS->GetPointD1D2( dUSE, ICurve::FROM_MINUS, ptSE) - || ! pCrvE->GetParamAtLength( dLenE, dUES) - || ! pCrvE->GetPointD1D2( dUES, ICurve::FROM_PLUS, ptES)) - return false ; - ICurveComposite* pCrvS_clone( pCrvS->Clone()) ; // curva di Offset iniziale accorciata - ICurveComposite* pCrvE_clone( pCrvE->Clone()) ; // curva di Offset finale accorciata - pCrvS_clone->ChangeStartPoint( dUSE) ; - pCrvE_clone->ChangeStartPoint( dUES) ; - - if ( ! pCrvS_clone->GetStartDir( vS) || ! pCrvE_clone->GetStartDir( vE)) - return false ; - - nIter++ ; - } - - pCrvLink->AddCurve( ptCrvFinal->Clone()) ; // ultimo arco valido trovato + if ( pCompo->GetExtrusion( vtExtr)) + pMCrv->SetExtrusion( vtExtr) ; return true ; } //---------------------------------------------------------------------------- bool -Pocketing::RemoveExtraParts( ISurfFlatRegion* pSrfToCut, ICRVCOMPOPOVECTOR& vOffs, ICRVCOMPOPOVECTOR& vOffsClosedCurves, ICRVCOMPOPOVECTOR& vOffsFirstCurve, ICURVEPOVECTOR& vLinks) { - - if ( pSrfToCut == nullptr || vOffs.size() == 0) - return true ; - - // ciclo tutti i chunk della regione da tagliare - for ( int i = 0 ; i < pSrfToCut->GetChunkCount() ; i++ ) { - - // prendo il bordo del chunk - PtrOwner pCrvChunkBorder( pSrfToCut->GetLoop( i, 0)) ; - if ( IsNull( pCrvChunkBorder)) - return false ; - - // 1) regione i-esima da rimuovere - PtrOwner pSrfChunkToCut( CreateSurfFlatRegion()) ; - if ( IsNull( pSrfChunkToCut)) - return false ; - if ( ! pSrfChunkToCut->AddExtLoop( pCrvChunkBorder->Clone())) - return false ; - - // 2) Curva nel caso la regione si svuoti con MedialAxis - PtrOwner pCrvPath( CreateCurveComposite()) ; - if ( IsNull( pCrvPath)) - return false ; - - // 3) Punto nel caso la regione si svuoti con un centroide - Point3d ptGoTo, ptGoToI ; - int nOptFlag ; - - if ( ! RemoveExtraPartByMedialAxis( pSrfChunkToCut, vOffsFirstCurve, nOptFlag, ptGoTo, pCrvPath) - || nOptFlag == 0) - continue ; - - if ( nOptFlag == 2 ) - if ( ! pCrvPath->GetStartPoint( ptGoTo) - || ! pCrvPath->GetEndPoint( ptGoToI)) - continue ; - - // 1) cerco la curva più vicina al punto trovato (ptGoTo) - PtrOwner pCrvH1( CreateCurveComposite()) ; - PtrOwner pCrvH2( CreateCurveComposite()) ; - PtrOwner pCrvH1I( CreateCurveComposite()) ; - PtrOwner pCrvH2I( CreateCurveComposite()) ; - - if ( pCrvH1 == nullptr || pCrvH2 == nullptr) - return false ; - int nIndexO = -1 ; - int nIndexOI = -1 ; - Point3d ptS, ptSI ; - - if ( ! GetClosestOffsetToAPoint( vOffs, ptGoTo, ptS, pCrvH1, pCrvH2, nIndexO)) - continue ; - if( nOptFlag == 2) - if ( ! GetClosestOffsetToAPoint( vOffs, ptGoToI, ptSI, pCrvH1I, pCrvH2I, nIndexOI)) - continue ; - - // A) SE SONO SU UN ESTREMO DELLA CURVA DI OFFSET -> Cerco un punto sui collegamenti - if ( pCrvH1 == nullptr || pCrvH2 == nullptr) { - bool bFound, bFoundI ; int nIndexL, nIndexLI ; - if ( ! GetClosestLinkToAPoint( vLinks, vOffs, ptGoTo, ptS, pCrvH1, pCrvH2, bFound, nIndexL)) - continue ; - if( nOptFlag == 2) - if ( ! GetClosestLinkToAPoint( vLinks, vOffs, ptGoToI, ptSI, pCrvH1I, pCrvH2I, bFoundI, nIndexLI)) - continue ; - - PtrOwner ptCrvNewLink( CreateCurveComposite()) ; - if ( ptCrvNewLink == nullptr) - return false ; - - if ( nOptFlag == 1) { - if ( ! GetNewCurvetWithCentroid( pCrvH1, pCrvH2, ptGoTo, bFound, vOffsFirstCurve, ptCrvNewLink)) - continue ; - } else if ( nOptFlag == 2) { - - bool bSucc = true; bool bSuccI = true ; - - if ( ! GetNewCurvetWithPath( pCrvH1, pCrvH2, pCrvPath, vOffsFirstCurve, vOffsClosedCurves, ptCrvNewLink)) - bSucc = false; - - double dLen, dLenI ; - PtrOwner pCrvPathI( pCrvPath->Clone()) ; - pCrvPathI->Invert() ; - PtrOwner ptCrvNewLinkI( CreateCurveComposite()) ; - if ( ptCrvNewLinkI == nullptr) - return false ; - - if ( ! GetNewCurvetWithPath( pCrvH1I, pCrvH2I, pCrvPathI, vOffsFirstCurve, vOffsClosedCurves, ptCrvNewLinkI)) - bSuccI = false; - - int nC = 0 ; - if ( bSucc && bSuccI) { - if ( ChoosePath( ptCrvNewLink, ptCrvNewLinkI, 0, 0.25, 5 * 1000 * EPS_SMALL, nC) && nC == 1) { - ptCrvNewLink.Set( Release( ptCrvNewLinkI)) ; - nIndexL = nIndexLI ; - } - } - else if ( ! bSucc) { - ptCrvNewLink.Set( Release( ptCrvNewLinkI)) ; - nIndexL = nIndexLI ; - } - } - vLinks[nIndexL].Set( Release( ptCrvNewLink)) ; - } - else { // B) SE NON SONO AD UN ESTREMO DELLA CURVA DI OFFSET - PtrOwner ptCrvNewOffs( CreateCurveComposite()) ; - if ( ptCrvNewOffs == nullptr) - return false ; - - if ( nOptFlag == 1) { - if ( ! GetNewCurvetWithCentroid( pCrvH1, pCrvH2, ptGoTo, true, vOffsFirstCurve, ptCrvNewOffs)) - continue ; - } - else if ( nOptFlag == 2) { // nel caso aggiungo un medial Axis non agli estremi di un Offset - - bool bSucc = true; bool bSuccI = true; - - if ( ! GetNewCurvetWithPath( pCrvH1, pCrvH2, pCrvPath, vOffsFirstCurve, vOffsClosedCurves, ptCrvNewOffs)) - bSucc == false ; - - double dLen, dLenI ; - PtrOwner pCrvPathI( pCrvPath->Clone()) ; - pCrvPathI->Invert() ; - PtrOwner ptCrvNewOffsI( CreateCurveComposite()) ; - if ( ptCrvNewOffsI == nullptr) - return false ; - - if ( ! GetNewCurvetWithPath( pCrvH1I, pCrvH2I, pCrvPathI, vOffsFirstCurve, vOffsClosedCurves, ptCrvNewOffsI)) - bSuccI = false ; - - int nC = 0 ; // se entrambi i percorsi sono validi allora li confronto - if ( bSucc && bSuccI) { - if ( ChoosePath( ptCrvNewOffs, ptCrvNewOffsI, 0, 0.5, 5 * 1000 * EPS_SMALL, nC) && nC == 1) { - ptCrvNewOffs.Set( Release( ptCrvNewOffsI)) ; - nIndexO = nIndexOI ; - } - } - else if ( ! bSucc) { - ptCrvNewOffs.Set( Release( ptCrvNewOffsI)) ; - nIndexO = nIndexOI ; - } - } - vOffs[nIndexO].Set( Release( ptCrvNewOffs)) ; - } - } - - return true ; -} - -//--------------------------------------------------------------------------- -bool -Pocketing::GetCurveWeightInfo( ICurveComposite* pCrvCompo, double dMaxLen, double& dToTRot, int& nSmallArcs, int& nSmallLines) { - - dToTRot = 0 ; nSmallArcs = 0 ; nSmallLines = 0 ; - if ( pCrvCompo == nullptr) - return true ; - - int nLines = 0 ; - PtrOwner pCrvLineOld( CreateCurveLine()) ; - - // scorro tutte le curve trovate - const ICurve* pMyCrv = pCrvCompo->GetFirstCurve() ; - while ( pMyCrv != nullptr) { - GeoObjType GeoType = pMyCrv->GetType() ; - if ( GeoType == CRV_ARC) { - nLines = 0 ; - PtrOwner pCrvArc( GetCurveArc(pMyCrv->Clone())) ; - double dAngCenter = abs( pCrvArc->GetAngCenter()) ; - dToTRot += dAngCenter ; - double dLen = 0 ; - if ( pCrvArc->GetLength( dLen) && dLen < dMaxLen) - nSmallArcs++ ; - } - else if ( GeoType == CRV_LINE) { // check nel caso non sia riuscito a smussare... - nLines++ ; - if ( nLines == 1) - pCrvLineOld.Set( GetCurveLine( pMyCrv->Clone())) ; - else { - PtrOwner pNewMyCrv( GetCurveLine( pMyCrv->Clone())) ; - Vector3d vtNew, vtOld ; - pCrvLineOld->GetEndDir( vtOld) ; - pNewMyCrv->GetStartDir( vtNew) ; - double dAngCorner ; vtOld.GetAngle( vtNew, dAngCorner) ; - dToTRot += abs( dAngCorner) ; - pCrvLineOld.Set( GetCurveLine( Release( pNewMyCrv))) ; - } - - double dLen = 0 ; - if ( pMyCrv->GetLength( dLen) && dLen < dMaxLen) - nSmallLines++ ; - } - pMyCrv = pCrvCompo->GetNextCurve() ; - } - - return true ; -} - -//--------------------------------------------------------------------------- -bool -Pocketing::ChoosePath( ICurveComposite* pCrv1, ICurveComposite* pCrv2, int nP, double dPerP, double dMaxLen, int& nC) { - - // controllo dei parametri - if ( pCrv1 == nullptr || pCrv2 == nullptr - || ! ( nP == 0 || nP == 1) - || dPerP > 1 || dPerP < 0 - || dMaxLen < EPS_SMALL) - return false ; - - // lunghezze... - double dLen1 = 0 ; double dLen2 = 0 ; - pCrv1->GetLength( dLen1) ; - pCrv2->GetLength( dLen2) ; - - double CL1, CL2 ; - - if ( dLen1 < EPS_SMALL && dLen2 < EPS_SMALL) { - CL1 = 0 ; - CL2 = 0 ; - } - else { - CL1 = dLen1 / max( dLen1, dLen2) ; - CL2 = dLen2 / max( dLen1, dLen2) ; - } - - // rotazioni... - double dRot1 = 0; double dRot2 = 0 ; int dSmallArcs1 = 0 ; int dSmallArcs2 = 0 ; int dSmallLines1 = 0 ; int dSmallLines2 = 0 ; - if ( ! GetCurveWeightInfo( pCrv1, dMaxLen, dRot1, dSmallArcs1, dSmallLines1) - || ! GetCurveWeightInfo( pCrv2, dMaxLen, dRot2, dSmallArcs2, dSmallLines2)) - return false ; - - double CR1, CR2 ; - - if ( dRot1 == 0 && dRot2 == 0) { - CR1 == 0 ; - CR2 == 0 ; - } - else { - CR1 = dRot1 / max( dRot1, dRot2) ; - CR2 = dRot2 / max( dRot1, dRot2) ; - } - - double Fp1 = ( nP == 0 ? dPerP : ( 1 - dPerP)) * (CL1 + dSmallLines1) + ( nP == 0 ? ( 1 - dPerP) : dPerP) * ( CR1 + dSmallArcs1) ; - double Fp2 = ( nP == 0 ? dPerP : ( 1 - dPerP)) * (CL2 + dSmallLines2) + ( nP == 0 ? ( 1 - dPerP) : dPerP) * ( CR2 + dSmallArcs2) ; - - nC = ( Fp1 > Fp2 ? 1 : 0) ; - return true ; -} - -//--------------------------------------------------------------------------- -bool -GetClosestOffsetToAPoint( ICRVCOMPOPOVECTOR& vCurves, Point3d& ptFocus, Point3d& ptCL, ICurveComposite* pCrv1, ICurveComposite* pCrv2, int& nIndex, bool bFirst) { - - // check paramtri - if ( vCurves.size() == 0) - return false ; - - // cerco il punto più vicino a ptFocus su ogni curva e scelgo quello a distanza minimia (da ptFocus) - Point3d ptCl_H ; - double dDistance = INFINITO ; - int nFlag ; - pCrv1->Clear() ; - pCrv2->Clear() ; - - if (vCurves.size() == 1) { - nIndex = 0 ; - if ( ! DistPointCurve( ptFocus, *vCurves[0]).GetMinDistPoint( EPS_SMALL, ptCL, nFlag)) - return false ; - } - - for ( int j = 1; j < vCurves.size(); j++ ) { - if ( ! DistPointCurve( ptFocus, *vCurves[j]).GetMinDistPoint( EPS_SMALL, ptCl_H, nFlag)) - return false ; - - if ( dDistance > Dist( ptCl_H, ptFocus)) { - dDistance = Dist( ptCl_H, ptFocus) ; - ptCL = ptCl_H ; - nIndex = j ; - } - } - if ( ! bFirst && vCurves.size() > 1) { - int nindexOld = nIndex ; dDistance = INFINITO ; - for ( int j = 1; j < vCurves.size(); j++ ) { - if ( j != nindexOld) { - if ( ! DistPointCurve( ptFocus, *vCurves[j]).GetMinDistPoint( EPS_SMALL, ptCl_H, nFlag)) - return false ; - - if ( dDistance > Dist( ptCl_H, ptFocus) ) { - dDistance = Dist( ptCl_H, ptFocus) ; - ptCL = ptCl_H ; - nIndex = j ; - } - } - } - } - - if ( nIndex < 0) - return false ; - - PtrOwner pCrv_H( vCurves[nIndex]->Clone()) ; - - // 2) Sulle curve di Offset ricavo: vettore iniziale, finale | punto iniziale, finale - Vector3d vtTanS, vtTanE, vtHelp ; double dUTan, dLenHelp, dUS, dUE ; bool bMustUseBiArcs = false ; - - if ( ! pCrv_H->GetParamAtPoint( ptCL, dUTan) || ! pCrv_H->GetDomain( dUS, dUE)) - return false ; - - pCrv1->AddCurve( GetCurveComposite( pCrv_H->CopyParamRange( dUS, dUTan))) ; - pCrv2->AddCurve( GetCurveComposite( pCrv_H->CopyParamRange( dUTan, dUE))) ; - - return true ; -} - -//--------------------------------------------------------------------------- -bool -GetClosestLinkToAPoint( ICURVEPOVECTOR& vCurves, ICRVCOMPOPOVECTOR& vOffs, Point3d& ptFocus, Point3d& ptCL, ICurveComposite* pCrv1, ICurveComposite* pCrv2, bool& bfound, int& nIndex) { - - double dDistance = INFINITO; - Point3d ptCl_H ; - int nFlag ; - pCrv1->Clear() ; - pCrv2->Clear() ; - bfound = false ; - - for ( int j = 1; j < vCurves.size(); j++ ) { - if ( ! DistPointCurve( ptFocus, *vCurves[j]).GetMinDistPoint( EPS_SMALL, ptCl_H, nFlag)) - return false ; - - if ( dDistance > Dist( ptCl_H, ptFocus) && ! ( vOffs[j-1]->IsPointOn( ptCl_H) || vOffs[j]->IsPointOn( ptCl_H))) { - dDistance = Dist( ptCl_H, ptFocus) ; - ptCL = ptCl_H ; - nIndex = j ; - bfound = true ; - } - } - - double dUS, dUE, dUTan ; - if ( ! vCurves[nIndex]->GetDomain( dUS, dUE) || ! vCurves[nIndex]->GetParamAtPoint( ptCL, dUTan)) - return false ; - pCrv1->AddCurve( GetCurve( vCurves[nIndex]->CopyParamRange( dUS, dUTan))) ; - pCrv2->AddCurve( GetCurve( vCurves[nIndex]->CopyParamRange( dUTan, dUE))) ; - - return true ; -} - - -//---------------------------------------------------------------------------- -bool -Pocketing::GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, Point3d& ptC, bool bCir, ICRVCOMPOPOVECTOR& VFirstOff, ICurveComposite* pCrvNewCurve) { - - ICurveComposite* pPath1( CreateCurveComposite()) ; - ICurveComposite* pPath2( CreateCurveComposite()) ; - if ( pPath1 == nullptr || pPath2 == nullptr) - return false ; - pCrvNewCurve->Clear() ; - Point3d ptS, ptE = ptC ; - Vector3d vtTanS, vtTanE ; - - if ( bCir) { // creo una circonferenza - // prendo il punto iniziale - if ( pCrvH1 == nullptr || pCrvH1->GetFirstCurve() == nullptr) { - if ( ! pCrvH2->GetStartPoint( ptS)) - return false ; - } - else { - if ( ! pCrvH1->GetEndPoint( ptS)) - return false ; - } - - // creo la circonferenza - if ( ! CalcBoundedSmootedLink( ptS, vtTanS, ptE, vtTanE, 0, VFirstOff, pPath1)) - return false ; - - // controllo che la circonferenza sia ammissibile ( solo che non esca dalle prime curve di Offset ) - Point3d ptCrvS ; pPath1->GetStartPoint( ptCrvS) ; - if ( ! CutCurveByOffsets( pPath1, VFirstOff)) { // taglio la curva sugli Offsets - return false ; - } - double dUCrvS ; - ModifyCurveToSmooted( pPath1, 0.075, 0.075) ; - if ( pPath1->IsClosed()) { - pPath1->GetParamAtPoint( ptCrvS, dUCrvS) ; - pPath1->ChangeStartPoint( dUCrvS) ; - } - - // creo la nuova curva con la circonferenza - if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) - if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio - return false ; - if ( ! pCrvNewCurve->AddCurve( pPath1->Clone())) // aggiungo la circonferenza - return false ; - if ( pCrvH2 != nullptr && pCrvH2->GetFirstCurve() != nullptr) - if ( !pCrvNewCurve->AddCurve(( pCrvH2->Clone()))) // aggiungo la fine - return false ; - } - else { // creo un BiArco - - // prendo il vettore tangente e il punto iniziale - if ( pCrvH1 == nullptr || pCrvH1->GetFirstCurve() == nullptr) { - if ( ! pCrvH2->GetStartDir( vtTanS) - || ! pCrvH2->GetStartPoint( ptS)) - return false ; - } - else { - if ( ! pCrvH1->GetEndDir( vtTanS) - || ! pCrvH1->GetEndPoint( ptS)) - return false ; - } - - // creo i due Biarchi - if ( ! CalcBoundedSmootedLink( ptS, vtTanS, ptE, vtTanS, 0.5, VFirstOff, pPath1) - || ! CalcBoundedSmootedLink( ptE, vtTanS, ptS, vtTanS, 0.5, VFirstOff, pPath2)) - return false ; - - // creo la nuova curva con il doppio Biarco - if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) - if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio - return false ; - if ( ! pCrvNewCurve->AddCurve( pPath1->Clone()) || ! pCrvNewCurve->AddCurve( pPath2->Clone())) // aggiungo i due BiArchi - return false ; - if ( pCrvH2 != nullptr && pCrvH2->GetFirstCurve() != nullptr) - if ( ! pCrvNewCurve->AddCurve(( pCrvH2->Clone()))) // aggiungo la fine - return false ; - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, ICRVCOMPOPOVECTOR& VFirstOff, ICRVCOMPOPOVECTOR& VoffsCl, ICurveComposite* pCrvNewCurve) { - - PtrOwner pPath1( CreateCurveComposite()) ; - PtrOwner pPath2( CreateCurveComposite()) ; - if ( pPath1 == nullptr || pPath2 == nullptr || pCrvPath == nullptr) - return false ; - pCrvNewCurve->Clear() ; - Point3d ptS, ptE, ptH ; - Vector3d vtTanS, vtTanE, vtH ; - - if ( ! pCrvPath->GetStartPoint( ptE) - || ! pCrvPath->GetStartDir( vtTanE) - || ! pCrvPath->GetEndPoint( ptH) - || ! pCrvPath->GetEndDir( vtH)) - return false ; - - if ( pCrvH1 == nullptr || pCrvH1->GetFirstCurve() == nullptr) { - if ( ! pCrvH2->GetStartPoint( ptS) - || ! pCrvH2->GetStartDir( vtTanS)) - return false ; - } - else { - if ( ! pCrvH1->GetEndPoint( ptS) - || ! pCrvH1->GetEndDir( vtTanS)) - return false ; - } - - // creo i due Biarchi - if ( ! CalcBoundedSmootedLink( ptS, vtTanS, ptE, vtTanE, 0.5, VFirstOff, pPath1)) - if( ! CalcBoundedLink( ptS, ptE, VFirstOff, pPath1)) - return false ; - if( ! CalcBoundedSmootedLink( ptH, vtH, ptS, vtTanS, 0.5, VFirstOff, pPath2)) - if( ! CalcBoundedLink( ptH, ptS, VFirstOff, pPath2)) - return false ; - - // creo la curva formata da BiArco1 - Path - BiArco 2 - PtrOwner pCrvToAdd( CreateCurveComposite()) ; - if ( pCrvToAdd == nullptr - || ! pCrvToAdd->AddCurve( pPath1->Clone()) - || ! pCrvToAdd->AddCurve( pCrvPath->Clone()) - || ! pCrvToAdd->AddCurve( pPath2->Clone())) - return false ; - - if ( ! ManageSmoothAndAutoInters( pCrvToAdd, pCrvPath, pPath1, pPath2, VoffsCl)) - return false ; - - // curva finale - if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) - if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio - return false ; - - if ( ! pCrvNewCurve->AddCurve( pCrvToAdd->Clone())) { // aggiungo BiArco - Path - BiArco - Vector3d vtHS, vtHE ; - Point3d ptHS, ptHE ; - pCrvNewCurve->GetEndPoint( ptHS) ; - pCrvNewCurve->GetEndDir( vtHS) ; - pCrvToAdd->GetStartPoint( ptHE) ; - pCrvToAdd->GetStartDir( vtHE) ; - PtrOwner pCrvBiArcHelper( CreateCurveComposite()) ; - if ( ! CalcBoundedSmootedLink( ptHS, vtHS, ptHE, vtHE, 0.5, VFirstOff, pCrvBiArcHelper)) - if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper)) - return false ; - if ( ! pCrvNewCurve->AddCurve( Release( pCrvBiArcHelper)) - || ! pCrvNewCurve->AddCurve( pCrvToAdd->Clone())) - return false ; - } - if ( pCrvH2 != nullptr && pCrvH2->GetFirstCurve() != nullptr) { - if ( ! pCrvNewCurve->AddCurve( pCrvH2->Clone())) { // aggiungo fine - int nTry = 1; int nMaxTry = 10 ; bool bFound = false; - while ( nTry < nMaxTry && ! bFound) { - Vector3d vtHS, vtHE ; - Point3d ptHS, ptHE ; - pCrvNewCurve->GetEndPoint( ptHS) ; - pCrvNewCurve->GetEndDir( vtHS) ; - pCrvH2->GetStartPoint( ptHE) ; - pCrvH2->GetStartDir( vtHE) ; - PtrOwner pCrvBiArcHelper( CreateCurveComposite()) ; - if ( ! CalcBoundedSmootedLink( ptHS, vtHS, ptHE, vtHE, 0.5, VFirstOff, pCrvBiArcHelper)) - if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper) ) - return false ; - if ( ! pCrvNewCurve->AddCurve( pCrvBiArcHelper->Clone()) - || ! pCrvNewCurve->AddCurve( pCrvH2->Clone())) { - nTry++; - } - else { - bFound = true ; - } - } - if ( ! bFound) - return false ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::ManageSmoothAndAutoInters( ICurveComposite* pCrv, ICurveComposite* pCrvPath, ICurveComposite* pPath1, ICurveComposite* pPath2, ICRVCOMPOPOVECTOR& vOffsCL) { - - // controllo parametri - if ( pCrv == nullptr) - return false ; - - // check AutoIntersezioni... - SelfIntersCurve SICrv( *pCrv) ; - if ( SICrv.GetCrossOrOverlapIntersCount() > 0) { // se ci sono autointersezioni - - Vector3d vTanE ; Point3d ptHS ; - pCrvPath->GetEndDir( vTanE) ; - pCrvPath->GetEndPoint( ptHS) ; - - bool bFound = false ; - int nIter = -45 ; - - while ( ! bFound && nIter < 45) { - vTanE.Rotate( Z_AX, 90 - nIter) ; // vettore perpendicolare - PtrOwner pLine( CreateCurveLine()) ; - pLine->SetPVL( ptHS, vTanE, m_TParams.m_dDiam / 3 - 5 * EPS_SMALL) ; // segmento uscente - - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *pLine, *pCrv) ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if ( ccClass.size() > 1) // se intersezione con parte precedente inverto la direzione - pLine->SetPVL( ptHS, - vTanE, m_TParams.m_dDiam / 3 - 5 * EPS_SMALL) ; - - if ( pLine == nullptr) - break ; - - // punto finale segmento uscente - Point3d ptEndLine ; - pLine->GetEndPoint( ptEndLine) ; - - - Point3d ptNear ; - double dUS, dUE ; - pPath2->GetDomain( dUS, dUE) ; - PtrOwner pCrvHelper( GetCurve( pPath2->CopyParamRange( dUS, dUE - 0.5))); - pCrvHelper->GetEndPoint( ptNear) ; - PtrOwner pLine1( GetLinePointTgCurve( ptEndLine, *pPath2, ptNear)) ; // segmento tangente - - if ( pLine1 == nullptr) - break ; - - // creo la nuova curva formata da BiArco 1 - Path - Segmento uscente - Segmento tangente - parte restante di Biarco 2 - Point3d ptELine1 ; - pLine1->GetEndPoint( ptELine1) ; - pPath2->GetParamAtPoint( ptELine1, dUS) ; - PtrOwner pNewPath2(( ICurveComposite*) GetCurve( pPath2->CopyParamRange( dUS, dUE))) ; - - - // creo la curva formata dai due segmenti ma smussati tra loro... - PtrOwner pCrvTwoSeg( CreateCurveComposite()) ; - if ( ! pCrvTwoSeg->AddCurve( pCrvPath->Clone()) - || ! pCrvTwoSeg->AddCurve( pLine->Clone()) - || ! pCrvTwoSeg->AddCurve( pLine1->Clone())) - return false ; - - ModifyCurveToSmooted( pCrvTwoSeg, 0.2, 0.2) ; - - PtrOwner ptNewCrv( CreateCurveComposite()); - if ( ptNewCrv->AddCurve( pPath1->Clone()) - && ptNewCrv->AddCurve( pCrvTwoSeg->Clone()) - && ptNewCrv->AddCurve( pNewPath2->Clone())) { - - SelfIntersCurve SICrvLoop( *ptNewCrv) ; - - if ( SICrvLoop.GetCrossOrOverlapIntersCount() == 0) { - pCrv->Clear() ; - pCrv->AddCurve( Release( ptNewCrv)) ; - bFound = true ; - } - else { // se trovo autointersezioni, ripeto cambiando l'angolo del segmento uscente - nIter++ ; - } - } - else - break ; - } - } - - // smusso questa curva sulle varie curve di offsets - Point3d ptCheck1, ptCheck2 ; - PtrOwner pCrvH( pCrv->Clone()) ; // copia della curva - - if ( ! CutCurveByOffsets( pCrv, vOffsCL)) { // taglio la curva sugli Offsets - pCrv->Clear() ; - pCrv->AddCurve( Release( pCrvH)) ; - } - else { // controllo che i punti iniziali coincidano - pCrv->GetStartPoint( ptCheck1) ; - pCrvH->GetStartPoint( ptCheck2) ; - if ( ! AreSamePointApprox( ptCheck1, ptCheck2)) { // se i punti iniziali della curva prima e dopo lo smusso non coincidono ... - pCrv->Clear() ; - pCrv->AddCurve ( Release( pCrvH)) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -RemoveFirstLoopFromSrfFlatRgn( ISurfFlatRegion* pSrfOrig) { - - if ( pSrfOrig == nullptr) - return true ; - - PtrOwner pSrfRes( CreateSurfFlatRegion()) ; - if ( pSrfRes == nullptr) - return false ; - - for ( int c = 1; c < pSrfOrig->GetChunkCount(); c++) { - PtrOwner pSrfHelp( CreateSurfFlatRegion()) ; - if ( pSrfHelp == nullptr) - return false ; - PtrOwner pCrvMiniChunkBorder( GetCurve( pSrfOrig->GetLoop(c, 0)->Clone())) ; - pSrfHelp->AddExtLoop( pCrvMiniChunkBorder->Clone()) ; - if ( c == 1) - pSrfRes.Set( pSrfHelp->Clone()) ; - else - pSrfRes->Add(*( pSrfHelp->Clone())) ; - } - - pSrfOrig->Clear() ; - pSrfOrig->CopyFrom( Release( pSrfRes)) ; - - return true ; -} - - - -//---------------------------------------------------------------------------- -bool -Pocketing::RemoveExtraPartByMedialAxis( ISurfFlatRegion* pChunkToCut, ICRVCOMPOPOVECTOR& vOffsFirstCurve, int& nOptFlag, Point3d& ptCentroid, ICurveComposite* pCrvPath) { - - nOptFlag = 2 ; - bool bForceCentroid = false ; - - if ( pChunkToCut == nullptr) - return false ; - - ICurveComposite* pCrvStepByStepPath( CreateCurveComposite()) ; // curva che l'utensile dovrà seguire per svuotare la regione - ICurveArc* pCrvToolShape( CreateCurveArc()) ; // superifice di ingobro del tool - if ( pCrvToolShape == nullptr || pCrvStepByStepPath == nullptr) - return false ; - - // copie del chunk che devo svuotare - ISurfFlatRegion* pSrfChunkToCutClone( pChunkToCut->Clone()) ; - double dArea = INFINITO ; - ICRVCOMPOPVECTOR vCrvCoMedAxi ; // vettore dei medial Axis - PNTVECTOR vPtCentroid ; // vettore di centroidi - int nIter = 0 ; // numero di iterazioni - - while ( pSrfChunkToCutClone != nullptr && pSrfChunkToCutClone->GetChunkCount() != 0 && pSrfChunkToCutClone->GetArea( dArea) && dArea > 10 * EPS_SMALL) { // finchè restano parti non svuotate la cui area totale è suffcientemente grande... - - if ( nIter > 25) - return false ; - - nIter++ ; - ISurfFlatRegion* pSrfBiggerChunk( CreateSurfFlatRegion()) ; - if ( pSrfBiggerChunk == nullptr || ! pSrfBiggerChunk->AddExtLoop( pSrfChunkToCutClone->GetLoop(0, 0))) - return false ; - - double dAreaExt ; - if ( pSrfBiggerChunk->GetArea( dAreaExt) && dAreaExt < 10 * EPS_SMALL) // se l'area del chunk è piccola... rimuovo il chunk dalla superficie da svuotare - { - if ( ! RemoveFirstLoopFromSrfFlatRgn( pSrfChunkToCutClone)) - return false ; - continue ; - } - - // prendo il centroide del chunk - Point3d ptC ; - if ( ! pSrfBiggerChunk->GetCentroid( ptC)) - return false ; - - // creo la superificie che racchiude il mio tool - pCrvToolShape->SetXY( ptC, m_TParams.m_dDiam / 2 + 5 * EPS_SMALL) ; - ISurfFlatRegion* pSrfTool( CreateSurfFlatRegion()) ; - if ( pSrfTool == nullptr || ! pSrfTool->AddExtLoop( pCrvToolShape)) - return false ; - - ISurfFlatRegion* pSrfChunkToCutCloneTest( pSrfBiggerChunk->Clone()) ; - if ( bForceCentroid || pSrfChunkToCutCloneTest->Subtract( *pSrfTool) && ! pSrfChunkToCutCloneTest->GetArea( dArea) && dArea < 10 * EPS_SMALL) { - if ( nIter == 1) { // se alla prima iterazione svuoto tutto con il centroide ... - nOptFlag = 1 ; - ptCentroid = ptC; - return true ; - } - else { // ... altrimenti devo prendere il centroide (che poi unirò al medil axis più vicino...) - for ( int cen = 0 ; cen < vPtCentroid.size(); cen++) { - if ( AreSamePointApprox( vPtCentroid[cen], ptC)) { - pSrfChunkToCutClone->Clear() ; - break ; - } - } - vPtCentroid.push_back( ptC) ; - if ( bForceCentroid) - pSrfChunkToCutClone->Subtract( *pSrfTool) ; - if ( ! pSrfChunkToCutClone->Subtract( *pSrfTool)) // o la pSrfBiggerChunk - return false ; - continue ; - } - } - bForceCentroid = false ; - - // 1) ricavo il bordo della regione - ICurve* pCrvBorder( pSrfBiggerChunk->GetLoop( 0, 0)) ; - if ( pCrvBorder == nullptr) - return false ; - - // 2) ricavo il medial Axis del bordo - PolyLine PlMedAx ; - if ( ! CurveSimpleMedialAxis( pCrvBorder, PlMedAx)) - return false ; - - ICurveComposite* pCrvMedAx( CreateCurveComposite()) ; - if ( pCrvMedAx == nullptr ) - return false; - - pCrvMedAx->Clear() ; - if ( ! pCrvMedAx->FromPolyLine( PlMedAx)) { // se non riesco ad aggiungere il medial axis non faccio nulla - //if ( ! RemoveFirstLoopFromSrfFlatRgn( pSrfChunkToCutClone)) - // return false ; - //continue ; - bForceCentroid = true ; - nIter --; - continue ; - } - - pCrvMedAx->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; - PolyArc PlMedAxArc ; - pCrvMedAx->ApproxWithArcsEx( 500 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PlMedAxArc) ; - pCrvMedAx->Clear(); - pCrvMedAx->FromPolyArc( PlMedAxArc) ; - - // smusso la curva - ModifyCurveToSmooted( pCrvMedAx, 0.025, 0.025) ; - // la inserisco nel vettore - vCrvCoMedAxi.push_back( pCrvMedAx->Clone()) ; - - // 3) guardo quale regione svuoto con questa curva - ISurfFlatRegion* pSrfRemoved = GetSurfFlatRegionFromFatCurve( pCrvMedAx->Clone(), m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, false, false) ; - if ( pSrfRemoved == nullptr ) - break ; - - // 4) aggiorno la regione togliendo la parte percorsa dal tool - if ( ! pSrfChunkToCutClone->Subtract( *pSrfRemoved)) - break ; - if ( pSrfChunkToCutClone == nullptr) - break ; - - } - - // Se il vettore è dei medial axis è vuoto allora l'area originaria era più piccola di 10 * EPS_SMALL - if ( vCrvCoMedAxi.size() == 0 && vPtCentroid.size() == 0) { - nOptFlag = 0 ; - return true ; - } - - // ora collego la varie curve medial Axis trovate tra loro (ottenendo quindi una curva che svuota tutta la regione) - ICurveComposite* pCrvCoBackLink( CreateCurveComposite()) ; - if ( pCrvCoBackLink == nullptr) - return false ; - Point3d ptSOriginal, ptEOriginal ; - Vector3d vtSOriginal, vtEOriginal ; - - if ( ! vCrvCoMedAxi[0]->GetStartPoint( ptSOriginal) // parametri iniziali del primo e ultimo medial Axis trovato - || ! vCrvCoMedAxi[vCrvCoMedAxi.size() -1]->GetEndPoint( ptEOriginal) - || ! vCrvCoMedAxi[0]->GetStartDir( vtEOriginal) - || ! vCrvCoMedAxi[vCrvCoMedAxi.size() - 1]->GetEndDir( vtSOriginal)) - return false ; - - pCrvPath->AddCurve( vCrvCoMedAxi[0]->Clone()) ; // inserisco il primo medial Axis nel percorso finale - - for ( int i = 1; i < vCrvCoMedAxi.size(); i++) { // scorro i restanti - Point3d ptS, ptE ; Vector3d vtS, vtE ; // parametri iniziali del medialAxis iesimo e (i-1)esimo - if ( ! vCrvCoMedAxi[i]->GetStartPoint( ptE) - || ! vCrvCoMedAxi[i-1]->GetEndPoint( ptS) - || ! vCrvCoMedAxi[i]->GetStartDir( vtE) - || ! vCrvCoMedAxi[i-1]->GetEndDir( vtS)) - return false ; - - ICurveComposite* pCrvCoLink( CreateCurveComposite()) ; - if ( pCrvCoLink == nullptr) - return false ; - - if ( ! CalcBoundedSmootedLink( ptS, vtS, ptE, vtE, 0.5, vOffsFirstCurve, pCrvCoLink)) - if ( ! CalcBoundedLink( ptS, ptE, vOffsFirstCurve, pCrvCoLink)) - return false ; - - if ( ! pCrvPath->AddCurve( pCrvCoLink) || ! pCrvPath->AddCurve( vCrvCoMedAxi[i]->Clone())) - return false ; - - } - - if ( ! AreSamePointEpsilon( ptEOriginal, ptSOriginal, EPS_SMALL)) - if ( ! CalcBoundedSmootedLink( ptEOriginal, vtSOriginal, ptSOriginal, vtEOriginal, 0.5, vOffsFirstCurve, pCrvCoBackLink)) - if ( ! CalcBoundedLink( ptEOriginal, ptSOriginal, vOffsFirstCurve, pCrvCoBackLink)) - return false ; - - pCrvPath->AddCurve( pCrvCoBackLink->Clone()) ; // percorso con tutti i medial Axis Collegati - // questa curva è chiusa e ha come punto iniziale/finale il punto finale del link della la curva di offset più vicina a questa regione svuotata - // la tengo chiusa in modo da unire facilmente le circonferenze che collegheranno i vari centroidi a questa curva - - // se ho trovato dei centroidi li unisco nei punti più vicino a questo percorso - for ( int i = 0; i < vPtCentroid.size(); i++) { - - // 1) cerco il punto sulla curva più vicino al centroide i - Point3d ptClosestOnPath ; int nFlag ; - if ( ! DistPointCurve( vPtCentroid[i], *pCrvPath).GetMinDistPoint( EPS_SMALL, ptClosestOnPath, nFlag)) - return false ; - // 2) imposto come punto iniziale della curva chiusa quest'ultimo punto - double dU; - if ( ! pCrvPath->GetParamAtPoint( ptClosestOnPath, dU)) - return false ; - pCrvPath->ChangeStartPoint( dU) ; - - // 3) prendo il vettore tangente al percorso nel punto PtClosestOnPath - Vector3d vtTanCpt ; - double dParClosest ; - ICurveComposite* pCrvCoHelpToTan( pCrvPath->Clone()) ; - if ( ! pCrvCoHelpToTan->GetStartDir( vtTanCpt)) - return false ; - - // 4) collego i due punti (centroide e punto più vicino alla curva) - ICurveComposite * pCrvPath1(CreateCurveComposite()) ; - if ( pCrvPath1 == nullptr) - return false ; - - if( ! CalcBoundedSmootedLink( ptClosestOnPath, vtTanCpt, vPtCentroid[i], vtTanCpt, 0, vOffsFirstCurve, pCrvPath1)) - if( ! CalcBoundedLink( ptClosestOnPath, vPtCentroid[i], vOffsFirstCurve, pCrvPath1)) - return false ; - if ( ! pCrvPath->AddCurve( pCrvPath1)) { - return false ; - } - } - - // riprendo il punto iniziale - double dU ; - if ( ! pCrvPath->GetParamAtPoint( ptSOriginal, dU)) - return false ; - pCrvPath->ChangeStartPoint( dU) ; - - // spezzo la curva nel punto PTEORIGINAL - if ( ! pCrvPath->GetParamAtPoint( ptEOriginal, dU)) - return false ; - PtrOwner ptCrvPathWithCut( GetCurve( pCrvPath->CopyParamRange(0, dU))) ; - if ( ptCrvPathWithCut == nullptr) - return false ; - pCrvPath->Clear(); - pCrvPath->AddCurve( Release( ptCrvPathWithCut)) ; - - // la curva resitituita è una curva aperta che ha come primo punto il punto iniziale del primo medialAxis - // la curva restituita collega tutti i medial Axis tra di loro - // la curva restitutita collega tutti i centroidi con delle circonferenze - // la curva restituita ha come punto finale l'ultimo punto dell'ultimo medial Axis - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink) -{ - pCrvLink->Clear() ; - - // recupero il vettore estrusione dal bordo esterno offsettato della superficie +Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound, + ICurveComposite* pCrvLink) +{ + // recupero il vettore estrusione Vector3d vtExtr ; - vOffIslands[0]->GetExtrusion( vtExtr) ; - + pCrvBound->GetExtrusion( vtExtr) ; // determino il riferimento naturale della svuotatura (OCS con il vettore estrusione come asse Z) Frame3d frLoc ; frLoc.Set( ORIG, vtExtr) ; - - // non serve collegare (può capitare nel tagliare percorsi con isole complesse) - if ( AreSamePointApprox( ptStart, ptEnd)) - return true ; - // porto la curva di contenimento in locale a questo riferimento - vector vOffsExtr ; - for ( int i = 0 ; i < vOffIslands.size(); i++) { - CurveLocal CrvOutLoc( vOffIslands[i], GLOB_FRM, frLoc) ; - vOffsExtr.push_back( CrvOutLoc) ; - } + CurveLocal CrvOutLoc( pCrvBound, GLOB_FRM, frLoc) ; // creo la retta che li unisce - PtrOwner pLine( CreateCurveComposite()) ; - if ( ! pLine->AddPoint( ptStart) || ! pLine->AddLine( ptEnd)) + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine) || ! pLine->Set( ptStart, ptEnd)) return false ; pLine->SetExtrusion( vtExtr) ; // la porto in locale al riferimento della svuotatura - CurveLocal LineLoc( pLine, GLOB_FRM, frLoc) ; // ... per le intersezioni - - // creo la nuova curva formata dai tratti di linee INTERNI alle isole e dai tratti sul bordo degli offset - PtrOwner pCompo( pLine->Clone()) ; - if ( IsNull( pCompo) ) - return false ; - if ( ! pCompo->LocToLoc( GLOB_FRM, frLoc) ) - return false; - - PtrOwner pCompoHelp( pLine->Clone()) ; - if ( IsNull( pCompoHelp)) - return false ; - if ( ! pCompoHelp->LocToLoc( GLOB_FRM, frLoc)) - return false ; - - // scorro il vettore degli indici degli offset delle isole intersecati - for ( int i = 0 ; i < vOffIslands.size(); i++ ) { - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *pCompo, *vOffIslands[i]) ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if ( ! pCompoHelp->Clear()) - return false ; - - for ( int j = 0 ; j < int( ccClass.size()) ; ++j ) { // per ogni intersezione j con l'offset dell'isola i - if ( ccClass[j].nClass == CRVC_OUT) { // se ho intersezione spezzo il segmento - Point3d ptS ; - pCompo->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; - double dOffS ; - vOffIslands[i]->GetParamAtPoint( ptS, dOffS) ; - Point3d ptE ; - pCompo->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; - double dOffE ; - vOffIslands[i]->GetParamAtPoint( ptE, dOffE) ; - // recupero i due possibili percorsi e uso il più corto - PtrOwner pCrvA( GetCurve( vOffIslands[i]->CopyParamRange( dOffS, dOffE))) ; - PtrOwner pCrvB( GetCurve( vOffIslands[i]->CopyParamRange( dOffE, dOffS))) ; - - if ( IsNull( pCrvA) || IsNull( pCrvB) ) - return false ; - double dLenA ; pCrvA->GetLength( dLenA) ; - double dLenB ; pCrvB->GetLength( dLenB) ; - if ( dLenA < dLenB ) { - pCompoHelp->AddCurve( Release( pCrvA)) ; - } - else { - pCrvB->Invert() ; - pCompoHelp->AddCurve( Release( pCrvB)) ; - } - } - else { // se non interseco - pCompoHelp->AddCurve( pCompo->Clone()->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; - } - } - - pCompo->Clear() ; - pCompo->AddCurve( pCompoHelp->Clone()) ; + CurveLocal LineLoc( pLine, GLOB_FRM, frLoc) ; + // classifico la curva di collegamento rispetto a quella di contenimento + CRVCVECTOR ccClass ; + IntersCurveCurve intCC( *LineLoc, *CrvOutLoc) ; + intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; + // se nessuno o un solo tratto e interno, la retta è il collegamento + if ( ccClass.empty() || ( ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN)) { + pCrvLink->AddCurve( Release( pLine)) ; + return true ; } - - // riporto pCompo nel sistema di riferimento originale - if ( ! pCompo->LocToLoc( frLoc, GLOB_FRM)) - return false ; - pCrvLink->AddCurve( Release( pCompo)) ; - - return true ; - -} - -//------------------------------------------------------------------------------ -bool -Pocketing::CalcBoundedSmootedLink( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd, const Vector3d& vtEnd, double dParMeet, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink) { - - // creo il BiArc che unisce i due punti - double dAngStart, dAngEnd ; - vtStart.GetAngleXY( X_AX, dAngStart) ; - vtEnd.GetAngleXY( X_AX, dAngEnd) ; - PtrOwner pBiArcLink ; - if ( dParMeet != 0) - pBiArcLink.Set( GetBiArc( ptStart, -dAngStart, ptEnd, -dAngEnd, dParMeet)) ; + // altrimenti combino i tratti interni di retta con tratti opportuni della curva di contenimento else { - ICurveArc* pCrvCir( CreateCurveArc()) ; - if ( pCrvCir == nullptr) + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo)) return false ; - pCrvCir->SetCPAN( Media( ptStart, ptEnd), ptStart, 360, 0, Z_AX) ; - pBiArcLink.Set( pCrvCir->Clone()) ; - pCrvLink->AddCurve( pBiArcLink->Clone()) ; - return true ; - } - if ( IsNull( pBiArcLink)) - return CalcBoundedLink( ptStart, ptEnd, vOffIslands, pCrvLink) ; - - // se BiArco troppo grande allora lo modifico - double dLenBiArc ; - pBiArcLink->GetLength( dLenBiArc) ; - if ( dLenBiArc > 200 * 1000 * EPS_SMALL) { - PtrOwner pCrvNewBiArcS( CreateCurveComposite()) ; - ModifyBiArc( pBiArcLink, 0.2, pCrvNewBiArcS) ; - pBiArcLink.Set( Release( pCrvNewBiArcS)) ; - } - - // creo la nuova curva formata inizialmente dai tratti di archi - PtrOwner pCompo( GetCurveComposite( pBiArcLink->Clone())) ; - if ( IsNull( pCompo)) - return false ; - - PtrOwner pCompoHelp( GetCurveComposite( pBiArcLink->Clone())) ; - if ( IsNull( pCompoHelp)) - return false ; - - // scorro tutte le curve per controllare le intersezioni ... - for ( int i = 0 ; i < vOffIslands.size(); i++) { - - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *pCompo, *vOffIslands[i]) ; - intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if ( ! pCompoHelp->Clear()) - return false ; - - for ( int j = 0 ; j < int( ccClass.size()) ; ++j ) { // per ogni intersezione j con l'offset dell'isola i - - if ( ccClass[j].nClass == CRVC_OUT && ccClass.size() > 1) { // se ho intersezione spezzo il segmento + for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) { + if ( ccClass[j].nClass == CRVC_IN || ccClass[j].nClass == CRVC_ON_P || ccClass[j].nClass == CRVC_ON_M) + pCompo->AddCurve( pLine->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ; + else if ( ccClass[j].nClass == CRVC_OUT) { Point3d ptS ; - pCompo->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; + pLine->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; double dOffS ; - vOffIslands[i]->GetParamAtPoint( ptS, dOffS) ; - Point3d ptE ; - pCompo->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; + pCrvBound->GetParamAtPoint( ptS, dOffS) ; + Point3d ptE ; + pLine->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; double dOffE ; - vOffIslands[i]->GetParamAtPoint( ptE, dOffE) ; - // recupero i due possibili percorsi e uso il più corto - PtrOwner pCrvA( GetCurve( vOffIslands[i]->CopyParamRange( dOffS, dOffE))) ; - PtrOwner pCrvB( GetCurve( vOffIslands[i]->CopyParamRange( dOffE, dOffS))) ; - - if (IsNull(pCrvA) || IsNull(pCrvB)) { - m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, vOffIslands[i]->Clone()); - m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()); - IGeoPoint3d* PTS(CreateGeoPoint3d()); IGeoPoint3d* PTE(CreateGeoPoint3d()); - PTS->Set( ptS) ; PTE->Set( ptE) ; - m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, PTS); - m_pGeomDB->AddGeoObj(GDB_ID_NULL, GDB_ID_ROOT, PTE); - return false; - } - + pCrvBound->GetParamAtPoint( ptE, dOffE) ; + // recupero i due possibili percorsi e uso il più corto + PtrOwner pCrvA( pCrvBound->CopyParamRange( dOffS, dOffE)) ; + PtrOwner pCrvB( pCrvBound->CopyParamRange( dOffE, dOffS)) ; + if ( IsNull( pCrvA) || IsNull( pCrvB)) + return false ; double dLenA ; pCrvA->GetLength( dLenA) ; double dLenB ; pCrvB->GetLength( dLenB) ; - - if ( j != 0) { - if ( dLenA < dLenB) { - if ( ! pCompoHelp->AddCurve( Release( pCrvA))) - return false ; - } - else { - pCrvB->Invert() ; - if ( ! pCompoHelp->AddCurve( Release( pCrvB))) - return false ; - } + if ( dLenA < dLenB) { + pCompo->AddCurve( Release( pCrvA)) ; } else { pCrvB->Invert() ; - if ( ! pCompoHelp->AddCurve( Release( pCrvB))) - return false ; + pCompo->AddCurve( Release( pCrvB)) ; } } - else { // se non interseco - if ( ! pCompoHelp->AddCurve( pCompo->Clone()->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) - return false ; - } } - - pCompo->Clear() ; - if ( ! pCompo->AddCurve( pCompoHelp->Clone())) - return false ; - - } - - // se il BiArco è troppo piccolo allora lo approssimo con un segmento - BBox3d bBox3 ; - if ( pCompo->GetLocalBBox( bBox3)) { - double dRadBB ; - if ( bBox3.GetRadius( dRadBB) && dRadBB < 500 * EPS_SMALL) { - if ( ! CalcBoundedLink( ptStart, ptEnd, vOffIslands, pCrvLink)) - return false ; - return true ; - } - } - - ModifyCurveToSmooted( pCompo, 0.05, 0.05) ; - pCrvLink->AddCurve( Release( pCompo)) ; - - return true ; -} - -//----------------------------------------------------------------------------- -bool -Pocketing::ModifyBiArc( ICurve* pBiArcLink, double dToll, ICurveComposite* pNewBiArc) { - - if ( pBiArcLink == nullptr) - return false ; - if ( dToll > 0.99 || dToll < 0.01) - return false ; - pNewBiArc->Clear() ; - - double dUS, dUE ; - pBiArcLink->GetDomain( dUS, dUE) ; - - PtrOwner pArc1( GetCurve( pBiArcLink->CopyParamRange( dUS, (dUS + dUE) / 2))) ; - PtrOwner pArc2( GetCurve( pBiArcLink->CopyParamRange(( dUS + dUE ) / 2, dUE))) ; - if ( pArc1 == nullptr || pArc2 == nullptr) - return false ; - - double dUTollS, dUTollE ; - - // primo pezzo - pArc1->GetDomain( dUS, dUE) ; - PtrOwner pArc1A( GetCurve( pArc1->CopyParamRange( dUS, dUS + ( dUE - dUS ) * dToll))) ; // Arc1 - PtrOwner pArc1B( GetCurve( pArc1->CopyParamRange( dUE - ( dUE - dUS ) * dToll, dUE))) ; // Arc2 - Point3d pt1A, pt1B ; - pArc1A->GetEndPoint( pt1A) ; - pArc1B->GetStartPoint( pt1B) ; - PtrOwner pLine1( CreateCurveLine()) ; - pLine1->Set( pt1A, pt1B) ; // Linea - - // secondo pezzo - pArc2->GetDomain(dUS, dUE) ; - PtrOwner pArc2A( GetCurve( pArc2->CopyParamRange( dUS, dUS + ( dUE - dUS ) * dToll))) ; // Arc1 - PtrOwner pArc2B( GetCurve( pArc2->CopyParamRange( dUE - ( dUE - dUS ) * dToll, dUE))) ; // Arc2 - Point3d pt2A, pt2B ; - pArc2A->GetEndPoint( pt2A) ; - pArc2B->GetStartPoint( pt2B) ; - PtrOwner pLine2( CreateCurveLine()) ; - pLine2->Set( pt2A, pt2B) ; // Linea - - if ( ! pNewBiArc->AddCurve( Release( pArc1A)) - || ! pNewBiArc->AddCurve( Release( pLine1)) - || ! pNewBiArc->AddCurve( Release( pArc1B)) - || ! pNewBiArc->AddCurve( Release( pArc2A)) - || ! pNewBiArc->AddCurve( Release( pLine2)) - || ! pNewBiArc->AddCurve( Release( pArc2B))) - return false ; - - return true ; -} - -//------------------------------------------------------------------------------ -bool -Pocketing::CutCurveByOffsets( ICurveComposite* pCurve, ICRVCOMPOPOVECTOR& vOffs) { - - // controllo parametri ingresso - if ( vOffs.size() == 0) + pCrvLink->AddCurve( Release( pCompo)) ; return true ; - - ICRVCOMPOPOVECTOR vOffOrig( vOffs.size()); - for ( int i = 0; i < vOffs.size(); i++ ) { - vOffOrig[i].Set(vOffs[i]->Clone()) ; } - - Point3d ptStart ; - if ( ! pCurve->GetStartPoint( ptStart)) - return false ; - - PtrOwner pCompo(( ICurveComposite* ) pCurve->Clone()) ; - PtrOwner pCompoHelp(( ICurveComposite* ) pCurve->Clone()) ; - PtrOwner pOffCheck( CreateCurveComposite()) ; - if ( pCompoHelp == nullptr || pCompo == nullptr || pOffCheck == nullptr) - return false ; - - int nTypeOfCut = -1 ; - bool bAttention = false ; - - for ( int i = 0; i < vOffOrig.size() ; i++) { - - if ( vOffOrig[i]->IsPointOn( ptStart)) - pOffCheck.Set( vOffOrig[i]->Clone()) ; - - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *pCompo, *vOffOrig[i]) ; - intCC.GetCurveClassification( 0, 10 * EPS_SMALL, ccClass) ; - - if ( ! pCompoHelp->Clear()) - return false ; - - if ( ccClass.size() > 1) { - if ( ccClass[0].nClass == CRVC_IN) - nTypeOfCut = CRVC_OUT ; - else - nTypeOfCut = CRVC_IN ; - - for ( int j = 0 ; j < int( ccClass.size()) ; ++j) { - if ( ccClass[j].nClass == nTypeOfCut) { - - Point3d ptS ; pCompo->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; - double dOffS ; vOffOrig[i]->GetParamAtPoint( ptS, dOffS) ; - Point3d ptE ; pCompo->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; - double dOffE ; vOffOrig[i]->GetParamAtPoint( ptE, dOffE) ; - // recupero i due possibili percorsi e uso il più corto - PtrOwner pCrvA( GetCurve( vOffOrig[i]->CopyParamRange( dOffS, dOffE))) ; - PtrOwner pCrvB( GetCurve( vOffOrig[i]->CopyParamRange( dOffE, dOffS))) ; - - if ( IsNull( pCrvA) || IsNull( pCrvB)) - return false ; - - double dLenA ; pCrvA->GetLength( dLenA) ; - double dLenB ; pCrvB->GetLength( dLenB) ; - - if ( dLenA < dLenB) { - - CRVCVECTOR ccClassA ; - IntersCurveCurve intCCA( *pCrvA, *pOffCheck) ; - intCCA.GetCurveClassification( 0, 10 * EPS_SMALL, ccClassA) ; - - if ( ccClassA.size() > 0 && i == vOffOrig.size() - 1 && ccClassA[0].nClass == CRVC_ON_M) { - if ( ! pCompoHelp->AddCurve( pCompo->Clone()->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) - return false ; - continue ; - } - - if ( ! pCompoHelp->AddCurve( Release( pCrvA))) - return false ; - } - else { - pCrvB->Invert() ; - - CRVCVECTOR ccClassB ; - IntersCurveCurve intCCB( *pCrvB, *pOffCheck) ; - intCCB.GetCurveClassification( 0, 10 * EPS_SMALL, ccClassB) ; - - if ( ccClassB.size() > 0 && i == vOffOrig.size() - 1 && ccClassB[0].nClass == CRVC_ON_M) { - if ( ! pCompoHelp->AddCurve( pCompo->Clone()->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) - return false ; - continue ; - } - - if ( ! pCompoHelp->AddCurve( Release( pCrvB))) - return false ; - } - } - else { - if ( ! pCompoHelp->AddCurve( pCompo->Clone()->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) - return false ; - } - } - - pCompo->Clear() ; - pCompo->AddCurve( pCompoHelp->Clone()) ; - } - } - - pCurve->Clear() ; - pCurve->AddCurve( Release( pCompo)) ; - - return true ; } //------------------------------------------------------------------------------ @@ -6551,7 +4046,7 @@ Pocketing::CalcBoundedLinkWithBiArcs( const Point3d& ptStart, const Vector3d& vt CRVCVECTOR ccClass ; IntersCurveCurve intCC( *pBiArcLink, *pCrvBound) ; intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - // se nessuno o un solo tratto e interno, il biarco è il collegamento + // se nessuno o un solo tratto e interno, il biarco è il collegamento if ( ccClass.empty() || ( ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN)) { pCrvLink->AddCurve( Release( pBiArcLink)) ; } @@ -6724,7 +4219,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD double dMaxLarg = b3Dim.GetDimY() ; // calcolo percorso di svuotatura - // se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale + // se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale if ( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && dMaxLarg > m_TParams.m_dDiam + 10 * EPS_SMALL && max( dLen0, dLen2) < 2 * m_TParams.m_dDiam + EPS_SMALL) { if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket)) { @@ -6737,7 +4232,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD if ( vnProp[0] != 0) dYCoord -= GetOffsR() ; if ( vnProp[0] != 0 && vnProp[2] != 0) - dYCoord = 0.5 * dPocketSize ; // se entrambi i lati paralleli sono aperti mi posiziono a metà della svuotatura + dYCoord = 0.5 * dPocketSize ; // se entrambi i lati paralleli sono aperti mi posiziono a metà della svuotatura double dXCoordStart, dXCoordEnd ; if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, true, dYCoord, dXCoordStart, dPocketSize)) @@ -6753,7 +4248,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD 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 + // 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())) ; @@ -6808,7 +4303,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD pMCrv->ToGlob( frLoc) ; if ( ! m_Params.m_bInvert) { pMCrv->Invert() ; - // inverto le proprietà in modo che nProp3 sia sempre legata al punto iniziale e nProp1 a quello finale + // inverto le proprietà in modo che nProp3 sia sempre legata al punto iniziale e nProp1 a quello finale swap( vnProp[1], vnProp[3]) ; } // segno i lati aperti come temp prop della curva @@ -6963,7 +4458,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC pMCrv->TrimStartAtParam( dPar) ; if ( ptP1.y > dPocketSize) { - // se ptP1 è esterno alla svuotatura scambio i punti in modo da usare ptP2 per il biarco ( così da non farlo fuoriuscire troppo) + // se ptP1 è esterno alla svuotatura scambio i punti in modo da usare ptP2 per il biarco ( così da non farlo fuoriuscire troppo) swap( ptP1, ptP2) ; pCompo->Invert() ; } @@ -6992,9 +4487,9 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC } } - // caso 2 : pLine è completamente sopra/sotto la linea di svuotatura + // caso 2 : pLine è completamente sopra/sotto la linea di svuotatura else { - // se è sopra modifiche per ricondurmi al caso in cui è sotto + // se è sopra modifiche per ricondurmi al caso in cui è sotto if ( ptP2.y > dYCoord) { pLine->Invert() ; swap( ptP1, ptP2) ; @@ -7021,7 +4516,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC } } - // se il lato opposto a quello di riferimento è chiuso ha senso aggiungere solo se il punto è sotto la linea di svuotatura + // se il lato opposto a quello di riferimento è chiuso ha senso aggiungere solo se il punto è sotto la linea di svuotatura else { if ( ptP2.y < dYCoord) { pCompo->AddPoint( ptP2) ; @@ -7031,7 +4526,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC } } - // setto temp prop per ricordare che è curva aggiuntiva per pulire angoli + // setto temp prop per ricordare che è curva aggiuntiva per pulire angoli for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) pCompo->SetCurveTempProp( i, 1) ; @@ -7098,7 +4593,7 @@ Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const } } - // se non è stato possibile creare raccordo, unisco linearmente + // se non è stato possibile creare raccordo, unisco linearmente if ( ! bUseBiArcs) pMCrv->AddCurve( Release( pLineLink)) ; @@ -7122,7 +4617,7 @@ Pocketing::AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite* pCompo, ICurv for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) { int nProp ; if ( pCompo->GetCurveTempProp( i, nProp) && nProp == 0) { - // se non è lato aggiuntivo per la pulitura angoli recupero la sua direzione + // se non è lato aggiuntivo per la pulitura angoli recupero la sua direzione pCompo->GetCurve( i)->GetStartDir( vtMainDir) ; break ; } @@ -7184,7 +4679,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - // tento con allungamento se lato inclinato è aperto oppure se sto considerando un lato aggiuntivo per pulire angoli + // tento con allungamento se lato inclinato è aperto oppure se sto considerando un lato aggiuntivo per pulire angoli if ( bEdgeOpen || nExtraEdge == 1) { Vector3d vtDirP = ( bLeadIn ? -vtDir : vtDir) ; @@ -7220,7 +4715,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V Point3d ptTest = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + dSafeZ) * dCorr) ; ptTest += - vtTool * dDepth ; double dTestElev ; - // se è fuori dal grezzo + // se è fuori dal grezzo if ( ! GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) || dTestElev < EPS_SMALL) { Point3d ptNewStart = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + dSafeZ) * dCorr) ; pCompo->AddLine( ptNewStart, ! bLeadIn) ; @@ -7229,7 +4724,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V } } - // tento con attacco ruotato di 90° se non sto considerando un tratto aggiuntivo per pulire angoli + // tento con attacco ruotato di 90° se non sto considerando un tratto aggiuntivo per pulire angoli if ( bBaseOpen && ! bIsOutsideRaw && nExtraEdge == 0) { Vector3d vtDirO = vtDir ; @@ -7245,7 +4740,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V Point3d ptTestO = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + dSafeZ) ; ptTestO += - vtTool * dDepth ; double dTestElevO ; - // se è fuori dal grezzo uso inizio ruotato + // se è fuori dal grezzo uso inizio ruotato if ( ! GetElevation( m_nPhase, ptTestO, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElevO) || dTestElevO < EPS_SMALL) { Point3d ptNewStart = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + dSafeZ) ; pCompo->AddLine( ptNewStart, ! bLeadIn) ; @@ -7274,11 +4769,11 @@ Pocketing::ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, if ( ! pMCrv->GetCurveTempProp( i, nProp)) return false ; - // se è un tratto di collegamento ho concluso percorso su cui aggiungere epicicli + // se è un tratto di collegamento ho concluso percorso su cui aggiungere epicicli if ( nProp == LINK_CURVE_PROP) { if ( pCompo->IsValid()) { PtrOwner pCrvEp( CreateCurveComposite()) ; - // la curva di bound è l'offset che calcolo in AddEpicycles per la prima curva compo trovata in pMCrv + // la curva di bound è l'offset che calcolo in AddEpicycles per la prima curva compo trovata in pMCrv bool bAddEp = ( ! pCrvBound->IsValid()) ? AddEpicycles( pCompo, pCrvEp, pCrvBound) : AddEpicycles( pCompo, pCrvEp) ; if ( ! bAddEp) return false ; @@ -7286,7 +4781,7 @@ Pocketing::ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, pCompo.Set( CreateCurveComposite()) ; } } - // se non è tratto di collegamento lo aggiungo alla curva + // se non è tratto di collegamento lo aggiungo alla curva else { if ( ! pCompo->AddCurve( pMCrv->GetCurve(i)->Clone())) return false ; @@ -7458,7 +4953,7 @@ Pocketing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafe // se con aggregato da sotto o equivalente (rinvio a 90 gradi su testa 5 assi) bool bBottomOutStart = false ; if ( m_bAggrBottom) { - // distanza dal bordo del pezzo (se negativa il punto è fuori dal grezzo) + // distanza dal bordo del pezzo (se negativa il punto è fuori dal grezzo) double dDistBottom ; if ( ! GetDistanceFromRawSide( m_nPhase, ptP, m_vtAggrBottom, dDistBottom)) dDistBottom = 0 ; @@ -7488,7 +4983,7 @@ Pocketing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafe SetFlag( 0) ; } } - // se sopra attacco c'è spazio per sicurezza o approccio + // se sopra attacco c'è spazio per sicurezza o approccio double dSafeDist = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ; if ( ! bBottomOutStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { // se distanza di sicurezza minore di distanza di inizio @@ -7534,7 +5029,7 @@ bool Pocketing::AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, double dElev, double dAppr, bool bOutStart) { - // se sopra attacco c'è spazio per approccio + // se sopra attacco c'è spazio per approccio if ( ( dElev + dAppr) > 10 * EPS_SMALL) { // 1b -> punto appena sopra inizio Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ; @@ -7563,7 +5058,7 @@ bool Pocketing::AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, double dElev, double dAppr) { - // se sopra uscita c'è spazio per approccio + // se sopra uscita c'è spazio per approccio if ( ( dElev + dAppr) > 10 * EPS_SMALL) { // 4 -> movimento di risalita sopra il punto finale SetFeed( GetEndFeed()) ; @@ -7588,7 +5083,7 @@ Pocketing::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ dDistBottom = 0 ; bBottomOutStart = ( dDistBottom < - 10 * EPS_SMALL) ; } - // se sopra uscita c'è spazio per sicurezza o approccio + // se sopra uscita c'è spazio per sicurezza o approccio double dSafeDist = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ; if ( ! bBottomOutStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { if ( dSafeDist < dAppr + 10 * EPS_SMALL) { @@ -7654,7 +5149,7 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con case POCKET_LI_GLIDE : { double dLen, dU ; - if ( ! pRCrv->GetLength( dLen) || ! pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU) || + if ( ! pRCrv->GetLength( dLen) || ! pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU) || ! pRCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP1)) { if ( ! pRCrv->GetStartPoint( ptP1)) return false ; @@ -7670,7 +5165,7 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con //---------------------------------------------------------------------------- bool Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, - ISurfFlatRegion* pSrfChunk, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, + const ICurveComposite* pCompo, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced, bool bSkipControl) { // Assegno il tipo @@ -7690,7 +5185,7 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 double dDeltaN = ( ptStart - ptP1) * vtN ; double dAngCen = ceil( - dDeltaN / ( m_Params.m_dLiElev + 20 * EPS_SMALL)) * ( bAtLeft ? ANG_FULL : - ANG_FULL) ; // verifico se fattibile - if ( bSkipControl || VerifyLeadInHelix( pSrfChunk, ptCen, dRad)) { + if ( bSkipControl || VerifyLeadInHelix( pCompo, ptCen, dRad)) { // creo l'elica PtrOwner pArc( CreateCurveArc()) ; if ( IsNull( pArc) || ! pArc->Set( ptCen, vtN, dRad, - vtCen, dAngCen, dDeltaN)) @@ -7720,7 +5215,7 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 Point3d ptPa = ptP1 + vtStart * 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam) ; Point3d ptPb = ptP1 - vtStart * 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam) ; // verifico se fattibile - if ( bSkipControl || VerifyLeadInZigZag( pSrfChunk, ptPa, ptPb)) { + if ( bSkipControl || VerifyLeadInZigZag( pCompo, ptPa, ptPb)) { for ( int i = 1 ; i <= nStep ; ++ i) { if ( AddLinearMove( ptPa - vtN * ( i - 0.75) * dStep, MCH_CL_LEADIN) == GDB_ID_NULL) return false ; @@ -7742,7 +5237,7 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 if ( pRCrv->GetLength( dLen) && pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU)) { double dParS, dParE ; pRCrv->GetDomain( dParS, dParE) ; - if ( ! pCrv.Set( CreateCurveComposite()) || ! pCrv->AddCurve( pRCrv->CopyParamRange( dU, dParE))) + if ( ! pCrv.Set( CreateCurveComposite()) || ! pCrv->AddCurve( pRCrv->CopyParamRange( dU, dParE))) return false ; } else { @@ -7875,7 +5370,7 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi } pMyCrv = pCompo->GetNextCurve() ; } - // richiedo lunghezza superiore a diametro utensile più doppio offset radiale + // richiedo lunghezza superiore a diametro utensile più doppio offset radiale double dRefLen = ( bAllOpen ? 0 : m_TParams.m_dDiam + 2 * GetOffsR() - EPS_SMALL) ; double dMaxLen = dRefLen ; // ciclo sulle singole curve @@ -7896,7 +5391,7 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi pNextCrv->GetLength( dLenNext) ; // verifico la curva corrente if ( pCrv->GetTempProp() == 1) { - // contributo dalle entità adiacenti (se non tutte aperte) + // contributo dalle entità adiacenti (se non tutte aperte) double dLenAgg = 0 ; if ( ! bAllOpen) { if ( pPrevCrv != nullptr && pPrevCrv->GetTempProp() == 1) { @@ -7910,34 +5405,34 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi dLenAgg += max( 0.4, vtEnd * vtNextStart) * dLenNext ; } } - // entità corrente + // entità corrente double dLen = 0 ; - if (pCrv->GetLength(dLen)) { - const double LEN_TOL = 1; - // se di lunghezza praticamente uguale - if (bFound && dLen + dLenAgg > dRefLen && abs(dLen + dLenAgg - dMaxLen) < LEN_TOL) { - Point3d ptTest; - pCrv->GetMidPoint(ptTest); - if ((m_bAboveHead && ptTest.z > ptMid.z + 100 * EPS_SMALL) || - (!m_bAboveHead && ptTest.z < ptMid.z - 100 * EPS_SMALL) || - (abs(ptTest.z - ptMid.z) < 100 * EPS_SMALL && ptTest.y < ptMid.y - 100 * EPS_SMALL)) { - dMaxLen = max(dMaxLen, dLen + dLenAgg); - ptMid = ptTest; - // vettore ortogonale verso l'esterno (ruotato -90deg attorno a estrusione) - pCrv->GetMidDir(vtMidOrt); - vtMidOrt.Rotate(vtExtr, 0, -1); + if ( pCrv->GetLength( dLen)) { + const double LEN_TOL = 1 ; + // se di lunghezza praticamente uguale + if ( bFound && dLen + dLenAgg > dRefLen && abs( dLen + dLenAgg - dMaxLen) < LEN_TOL) { + Point3d ptTest ; + pCrv->GetMidPoint( ptTest) ; + if ( ( m_bAboveHead && ptTest.z > ptMid.z + 100 * EPS_SMALL) || + ( ! m_bAboveHead && ptTest.z < ptMid.z - 100 * EPS_SMALL) || + ( abs( ptTest.z - ptMid.z) < 100 * EPS_SMALL && ptTest.y < ptMid.y - 100 * EPS_SMALL)) { + dMaxLen = max( dMaxLen, dLen + dLenAgg) ; + ptMid = ptTest ; + // vettore ortogonale verso l'esterno (ruotato -90deg attorno a estrusione) + pCrv->GetMidDir( vtMidOrt) ; + vtMidOrt.Rotate( vtExtr, 0, -1) ; } } - // se pi� lunga - else if (dLen + dLenAgg > dMaxLen) { - dMaxLen = dLen + dLenAgg; - pCrv->GetMidPoint(ptMid); - // vettore ortogonale verso l'esterno (ruotato -90deg attorno a estrusione) - pCrv->GetMidDir(vtMidOrt); - vtMidOrt.Rotate(vtExtr, 0, -1); - bFound = true; + // se più lunga + else if ( dLen + dLenAgg > dMaxLen) { + dMaxLen = dLen + dLenAgg ; + pCrv->GetMidPoint( ptMid) ; + // vettore ortogonale verso l'esterno (ruotato -90deg attorno a estrusione) + pCrv->GetMidDir( vtMidOrt) ; + vtMidOrt.Rotate( vtExtr, 0, -1) ; + bFound = true ; } - dLenPrev = dLen; + dLenPrev = dLen ; } } else @@ -7960,7 +5455,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) Frame3d frPocket ; Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; frPocket.Set( ptStart, vtExtr) ; - // sposto l'inizio a metà del tratto più lungo + // sposto l'inizio a metà del tratto più lungo AdjustContourStart( pCompo) ; // raggio di riferimento per offset double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ; @@ -8079,7 +5574,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) bool Pocketing::AdjustContourStart( ICurveComposite* pCompo) { - // cerco il tratto lineare più lungo che non sia aperto + // cerco il tratto lineare più lungo che non sia aperto int i = 0 ; int nMax = - 1 ; double dLenMax = 0 ; @@ -8093,7 +5588,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo) ++ i ; pCrv = pCompo->GetNextCurve() ; } - // se non trovato o troppo corto, cerco il tratto generico più lungo + // se non trovato o troppo corto, cerco il tratto generico più lungo if ( nMax < 0 || dLenMax < 2 * m_TParams.m_dDiam) { i = 0 ; pCrv = pCompo->GetFirstCurve() ; @@ -8117,70 +5612,28 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo) //---------------------------------------------------------------------------- bool -Pocketing::VerifyLeadInHelix( ISurfFlatRegion* pSrfChunk, const Point3d& ptCen, double dRad) const +Pocketing::VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const { - // controllo della superifice - if ( pSrfChunk == nullptr) - return false ; - - // vettore di tutte le curve della superficie - ICRVCOMPOPOVECTOR vCrv ; - for( int c = 0 ; c < pSrfChunk->GetChunkCount() ; c++) { - for ( int l = 0 ; l < pSrfChunk->GetLoopCount( c) ; l++) { - vCrv.emplace_back( CloneCurveComposite( pSrfChunk->GetLoop( c, l))) ; - } - } - if ( vCrv.size() == 0) - return false ; - - // estraggo il bordo esterno - PtrOwner pCompo( CloneCurveComposite( vCrv[0])) ; - if ( IsNull( pCompo)) - return false ; - // recupero il piano della curva di contorno Point3d ptStart ; Vector3d vtN ; - if ( ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) + if ( pCompo == nullptr || ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) return false ; // porto il centro sullo stesso piano del contorno Point3d ptCenL = ptCen - ( ptCen - ptStart) * vtN * vtN ; // calcolo la distanza del centro dal contorno double dMinDist ; - bool bOk = DistPointCurve( ptCenL, *pCompo).GetDist( dMinDist) && dMinDist > dRad + 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL ; - // se la curva per l'attacco è valida per tale, controllo che l'elica non intersechi eventuali isole - for ( int i = 1 ; bOk && i < vCrv.size() ; i++) - bOk = DistPointCurve( ptCenL, *vCrv[i]).GetDist( dMinDist) && dMinDist > dRad + 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL ; - return bOk ; + return ( DistPointCurve( ptCenL, *pCompo).GetDist( dMinDist) && dMinDist > dRad + 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ; } //---------------------------------------------------------------------------- bool -Pocketing::VerifyLeadInZigZag( ISurfFlatRegion* pSrfChunk, const Point3d& ptPa, const Point3d& ptPb) const +Pocketing::VerifyLeadInZigZag( const ICurveComposite* pCompo, const Point3d& ptPa, const Point3d& ptPb) const { - // controllo della superificie - if ( pSrfChunk == nullptr) - return false ; - - // vettore di tutte le curve della superficie - ICRVCOMPOPOVECTOR vCrv ; - for ( int c = 0 ; c < pSrfChunk->GetChunkCount() ; c++) { - for ( int l = 0 ; l < pSrfChunk->GetLoopCount( c) ; l++) { - vCrv.emplace_back( CloneCurveComposite( pSrfChunk->GetLoop( c, l))) ; - } - } - if ( vCrv.size() == 0) - return false ; - - // estraggo il bordo esterno - PtrOwner pCompo( CloneCurveComposite( vCrv[0])) ; - if ( IsNull( pCompo)) - return false ; - // recupero il piano della curva di contorno Point3d ptStart ; Vector3d vtN ; - if ( ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) + if ( pCompo == nullptr || ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) return false ; // porto i punti sullo stesso piano del contorno Point3d ptPaL = ptPa - ( ptPa - ptStart) * vtN * vtN ; @@ -8192,17 +5645,7 @@ Pocketing::VerifyLeadInZigZag( ISurfFlatRegion* pSrfChunk, const Point3d& ptPa, double dMinDistPb ; if ( ! DistPointCurve( ptPbL, *pCompo).GetDist( dMinDistPb)) return false ; - bool bOk = dMinDistPa > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL && dMinDistPb > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL ; - // se la curva per l'attacco è valida per tale, controllo che lo ZigZag non intersechi eventuali isole - for ( int i = 1 ; bOk && i < vCrv.size() ; i++) { - if ( ! DistPointCurve( ptPaL, *vCrv[i]).GetDist( dMinDistPa)) - return false ; - if ( ! DistPointCurve( ptPbL, *vCrv[i]).GetDist( dMinDistPb)) - return false ; - bOk = dMinDistPa > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL && dMinDistPb > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL ; - } - return bOk ; - + return ( dMinDistPa > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL && dMinDistPb > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ; } //---------------------------------------------------------------------------- diff --git a/Pocketing.h b/Pocketing.h index 27d1dd3..7afb60c 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -19,7 +19,6 @@ #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EgtNumUtils.h" -#include "/EgtDev/Include/EGkSurfFlatRegion.h" //---------------------------------------------------------------------------- class Pocketing : public Machining @@ -74,18 +73,13 @@ class Pocketing : public Machining bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ; - bool VerifyPathFromBottom( const ISurfFlatRegion* pSrf, const Vector3d& vtTool) ; - bool GeneratePocketingPv( int nPathId, const ISurfFlatRegion* pSrfPock) ; - - bool ModifyCurveToSmooted( ICurveComposite* pCrvOffset, double dRightPer, double dleftPer) ; - - // ===== ZigZag ===== - bool AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, - bool bSplitArcs, int nPathId) ; - bool CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpCrvs) ; - bool CalcBoundedZigZagLink( ICurveLine* pCrv1, ICurveLine* pCrv2, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink, int nIndexCut = 3) ; - bool OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d & vtTool, double dDepth, double dSafeZ, Frame3d & frPocket, bool & bOptimizedZigZag, - ICRVCOMPOPOVECTOR & vpCrvs) ; + bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ; + bool GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) ; + bool AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) ; + bool CalcZigZag( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; + bool OptimizedZigZag( int nPathId, const Vector3d& vtTool, double dDepth, double dSafeZ, + Frame3d& frPocket, bool& bOptimizedZigZag, ICRVCOMPOPOVECTOR& vpCrvs) ; bool ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOptimizedZigZag, Vector3d& vtDir) ; bool ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClosedId, bool& bOptimizedZigZag, Vector3d& vtDir) ; bool ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INTVECTOR& vnClosedIds, bool& bOptimizedZigZag, @@ -95,38 +89,17 @@ class Pocketing : public Machining bool ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vector3d& vtMainDir, int nOffsettedEdgesOnY, const INTVECTOR& vnClosedIds) ; bool CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) ; - bool GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICURVEPOVECTOR& vLinks, ISurfFlatRegion* pSrfToCut) ; - // ================== - - // ==== OneWay ====== - bool AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; - // ================== - - // ==== SpiralIn/Out ==== - bool AddSpiralIn( const ISurfFlatRegion* pSrfPock, const PNTVECTOR vPtStart, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, - double dElev, double dOkStep, bool bSplitArcs, BOOLVECTOR vbMidOpen, PNTVECTOR vPtMidOpen, VCT3DVECTOR vVtMidOut, int nPathId) ; - bool AddSpiralOut( const ISurfFlatRegion* pSrfpock, const PNTVECTOR vPtStart, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, - double dOkStep, bool bSplitArcs, int nPathId) ; - bool CalcSpiral( const ISurfFlatRegion* pSrfChunk, int nReg, Point3d ptStart, bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv, int nPathId, - bool& bOptimizedTrap) ; - bool RemoveExtraParts( ISurfFlatRegion* pSrfToCut, ICRVCOMPOPOVECTOR& vOffs, ICRVCOMPOPOVECTOR& vOffsClosedCurves, ICRVCOMPOPOVECTOR& vOffsFirstCurve, - ICURVEPOVECTOR& vLinks) ; - bool RemoveExtraPartByMedialAxis( ISurfFlatRegion* pChunkToCut, ICRVCOMPOPOVECTOR& vOffsFirstCurve, int& nOptFlag, Point3d& ptCentroid, - ICurveComposite* pCrvPath) ; - bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink) ; - bool CalcBoundedSmootedLink( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd, const Vector3d& vtEnd, double dParMeet, - ICRVCOMPOPOVECTOR& vOffIslands, ICurveComposite* pCrvLink) ; - bool ModifyBiArc( ICurve* pCrvBiArc, double dCutToll, ICurveComposite* pNewCrv) ; - bool CutCurveByOffsets( ICurveComposite* pCurve, ICRVCOMPOPOVECTOR& vOffs) ; - bool GetCurveWeightInfo( ICurveComposite* pCrvCompo, double dMaxLen, double& dToTRot, int& nSmallArcs, int& nSmallLines) ; - bool ChoosePath( ICurveComposite* pCrv1, ICurveComposite* pCrv2, int nP, double dPerP, double dMaxLen, int& nC) ; - bool CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, ICRVCOMPOPOVECTOR& vOffs, ICRVCOMPOPOVECTOR& vOffIslands, - ICurveComposite* pCrvLink, double dLenPercS = 0.01, double dLenPercE = 0.01, int nMaxIter = 2) ; - bool GetNewCurvetWithCentroid( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, Point3d& ptC, bool bCir, ICRVCOMPOPOVECTOR& VFirstOff, - ICurveComposite* pCrvNewCurve) ; - bool GetNewCurvetWithPath( ICurveComposite* pCrvH1, ICurveComposite* pCrvH2, ICurveComposite* pCrvPath, ICRVCOMPOPOVECTOR& VFirstOff, ICRVCOMPOPOVECTOR& VoffsCl, - ICurveComposite* pCrvNewCurve) ; - bool ManageSmoothAndAutoInters( ICurveComposite* pCrv, ICurveComposite* pCrvPath, ICurveComposite* pPath1, ICurveComposite* pPath2, ICRVCOMPOPOVECTOR& vOffsCL) ; + bool AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; + bool AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, bool bMidOpen, + const Point3d& ptMidOpen, const Vector3d& vtMidOut, int nPathId) ; + bool AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) ; + bool CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, + ICurveComposite* pMCrv, ICurveComposite* pRCrv, int nPathId, bool& bOptimizedTrap) ; + bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound, + ICurveComposite* pCrvLink) ; bool CalcBoundedLinkWithBiArcs( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd, const Vector3d& vtEnd, const ICurve* pCrvBound, ICurveComposite* pCrvLink) ; bool CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad, @@ -139,10 +112,7 @@ class Pocketing : public Machining bool SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveComposite* pCrvPocket) ; bool AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite * pCompo, ICurveComposite * pRCrv, const Vector3d& vtTool, double dDepth, int& nOutsideRaw) ; - bool ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite * pCompo, const Vector3d& vtMainDir, bool bLeadIn, const Vector3d& vtTool, double dDepth, - bool& bIsOutsideRaw) ; - // ================== - + bool ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite * pCompo, const Vector3d& vtMainDir, bool bLeadIn, const Vector3d& vtTool, double dDepth, bool& bIsOutsideRaw) ; bool ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool bSplitArcs) ; bool AddEpicycles( ICurveComposite * pCompo, ICurveComposite * pCrv, ICurveComposite * pCrvBound = nullptr) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, @@ -155,8 +125,8 @@ class Pocketing : public Machining double dElev, double dAppr) ; bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, const ICurveComposite* pRCrv, Point3d& ptP1) const ; - bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, - ISurfFlatRegion* pSrfChunk, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, + bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + const ICurveComposite* pCompo, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced = false, bool bSkipControl = false) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced = false) ; @@ -164,8 +134,8 @@ class Pocketing : public Machining bool GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMid, Vector3d& vtMidOut) ; bool AdjustContourWithOpenEdges( ICurveComposite* pCompo) ; bool AdjustContourStart( ICurveComposite* pCompo) ; - bool VerifyLeadInHelix( ISurfFlatRegion* pSrfChunk, const Point3d& ptCen, double dRad) const ; - bool VerifyLeadInZigZag( ISurfFlatRegion* pSrfChunk, const Point3d& ptPa, const Point3d& ptPb) const ; + bool VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const ; + bool VerifyLeadInZigZag( const ICurveComposite* pCompo, const Point3d& ptPa, const Point3d& ptPb) const ; bool CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist, Vector3d& vtNorm) ; private : @@ -217,5 +187,4 @@ class Pocketing : public Machining Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo - POLYLINEVECTOR m_VplIsland ; // vettore che contiene le curve che descrivono le isole } ; \ No newline at end of file