From baedb87cd1298fb5ca16d8abdfdf5c5273d3b95b Mon Sep 17 00:00:00 2001 From: SaraP Date: Fri, 28 May 2021 17:14:25 +0200 Subject: [PATCH] EgtMachKernel : - svuotature con isole, prima implementazione. --- Pocketing.cpp | 3002 ++++++++++++++++++++++++++++++------------------- Pocketing.h | 53 +- 2 files changed, 1874 insertions(+), 1181 deletions(-) diff --git a/Pocketing.cpp b/Pocketing.cpp index d38f1f7..54d4404 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -95,9 +95,9 @@ Pocketing::GetClassName( void) const Pocketing* Pocketing::Clone( void) const { - // alloco oggetto + // alloco oggetto Pocketing* pPock = new(nothrow) Pocketing ; - // eseguo copia dei dati + // eseguo copia dei dati if ( pPock != nullptr) { try { pPock->m_vId = m_vId ; @@ -116,7 +116,7 @@ Pocketing::Clone( void) const return nullptr ; } } - // ritorno l'oggetto + // ritorno l'oggetto return pPock ; } @@ -167,15 +167,15 @@ Pocketing::Save( int nBaseId, STRVECTOR& vString) const //---------------------------------------------------------------------------- bool Pocketing::Load( const STRVECTOR& vString, int nBaseGdbId) -{ +{ int nSize = int( vString.size()) ; - // lista identificativi geometrie da lavorare + // lista identificativi geometrie da lavorare int k = - 1 ; if ( k >= nSize - 1 || ! GetVal( vString[++k], KEY_IDS, m_vId)) return false ; for ( auto& Sel : m_vId) Sel.nId += nBaseGdbId ; - // parametri lavorazione + // parametri lavorazione for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) { int nKey ; if ( k >= nSize - 1 || ! m_Params.FromString( vString[++k], nKey) || nKey != i) { @@ -185,18 +185,18 @@ Pocketing::Load( const STRVECTOR& vString, int nBaseGdbId) return false ; } } - // parametri utensile + // parametri utensile for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) { int nKey ; if ( k >= nSize - 1 || ! m_TParams.FromString( vString[++k], nKey) || nKey != i) return false ; } - // parametri di stato + // parametri di stato while ( k < nSize - 1) { - // separo chiave da valore + // separo chiave da valore string sKey, sVal ; SplitFirst( vString[++k], "=", sKey, sVal) ; - // leggo + // leggo if ( sKey == KEY_PHASE) { if ( ! FromString( sVal, m_nPhase)) return false ; @@ -235,23 +235,23 @@ Pocketing::Pocketing( void) bool Pocketing::Prepare( const string& sMillName) { - // verifico il gestore lavorazioni + // verifico il gestore lavorazioni if ( m_pMchMgr == nullptr) return false ; - // recupero il gestore DB utensili della macchina corrente + // recupero il gestore DB utensili della macchina corrente ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; if ( pTMgr == nullptr) return false ; - // recupero il gestore DB lavorazioni della macchina corrente + // recupero il gestore DB lavorazioni della macchina corrente MachiningsMgr* pMMgr = m_pMchMgr->GetCurrMachiningsMgr() ; if ( pMMgr == nullptr) return false ; - // ricerca della lavorazione di libreria con il nome indicato + // ricerca della lavorazione di libreria con il nome indicato const PocketingData* pDdata = GetPocketingData( pMMgr->GetMachining( sMillName)) ; if ( pDdata == nullptr) return false ; m_Params = *pDdata ; - // ricerca dell'utensile usato dalla lavorazione + // ricerca dell'utensile usato dalla lavorazione const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; @@ -377,7 +377,7 @@ Pocketing::SetParam( int nType, double dVal) if ( sVal != m_Params.m_sDepth) m_nStatus |= MCH_ST_PARAM_MODIF ; m_Params.m_sDepth = sVal ; - } return true ; + } return true ; case MPA_STARTPOS : if ( abs( dVal - m_Params.m_dStartPos) > EPS_MACH_LEN_PAR) m_nStatus |= MCH_ST_PARAM_MODIF ; @@ -431,7 +431,7 @@ Pocketing::SetParam( int nType, const string& sVal) m_Params.m_sToolName = sVal ; m_Params.m_ToolUuid = pTdata->m_Uuid ; m_TParams = *pTdata ; - } return true ; + } return true ; case MPA_DEPTH_STR : if ( sVal != m_Params.m_sDepth) m_nStatus |= MCH_ST_PARAM_MODIF ; @@ -465,27 +465,27 @@ 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 + // 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) ; m_pMchMgr->SetWarning( 2451, sInfo) ; continue ; } - // posso aggiungere alla lista + // posso aggiungere alla lista m_vId.emplace_back( Id) ; } - // aggiorno lo stato + // aggiorno lo stato m_nStatus |= MCH_ST_GEO_MODIF ; - // restituisco presenza geometria da lavorare + // restituisco presenza geometria da lavorare return ( ! m_vId.empty() || vIds.empty()) ; } @@ -493,17 +493,17 @@ Pocketing::SetGeometry( const SELVECTOR& vIds) bool Pocketing::Preview( bool bRecalc) { - // reset numero percorsi di svuotatura generati + // 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 + // 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) @@ -512,50 +512,50 @@ Pocketing::Preview( bool bRecalc) m_pGeomDB->SetStatus( nAuxId, GDB_ST_OFF) ; bChain = true ; } - // altrimenti, se chiesto ricalcolo, lo svuoto + // altrimenti, se chiesto ricalcolo, lo svuoto else if ( bRecalc) { m_pGeomDB->EmptyGroup( nAuxId) ; bChain = true ; } - // aggiorno dati geometrici dell'utensile + // aggiorno dati geometrici dell'utensile if ( ! UpdateToolData()) { m_pMchMgr->SetLastError( 2401, "Error in Pocketing : UpdateToolData failed") ; return false ; } - // rendo corrente l'utensile usato nella lavorazione + // rendo corrente l'utensile usato nella lavorazione if ( ! m_pMchMgr->SetCalcTool( m_TParams.m_sName, m_TParams.m_sHead, m_TParams.m_nExit)) { m_pMchMgr->SetLastError( 2428, "Error in Pocketing : Tool loading failed") ; return false ; } - // recupero i dati del portautensile + // recupero i dati del portautensile int nToolId = m_pMchMgr->GetCalcTool() ; m_dTHoldLen = 0 ; m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ; m_dTHoldDiam = 0 ; m_pGeomDB->GetInfo( nToolId, TTH_DIAM, m_dTHoldDiam) ; - // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria if ( bChain && ! Chain( nAuxId)) { m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Chaining failed") ; return false ; } - // recupero gruppo per geometria di Preview + // 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) return false ; m_pGeomDB->SetName( nPvId, MCH_PV) ; } - // altrimenti lo svuoto + // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nPvId) ; - // lavoro ogni singola catena + // lavoro ogni singola catena int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; while ( nPathId != GDB_ID_NULL) { if ( ! ProcessPath( nPathId, nPvId, GDB_ID_NULL)) @@ -570,37 +570,37 @@ Pocketing::Preview( bool bRecalc) bool Pocketing::Apply( bool bRecalc, bool bPostApply) { - // reset numero percorsi di svuotatura generati + // reset numero percorsi di svuotatura generati int nCurrPockets = m_nPockets ; m_nPockets = 0 ; - // reset raggio massimo attacco ad elica nel caso di cerchi + // 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 ; - // aggiorno dati geometrici dell'utensile + // aggiorno dati geometrici dell'utensile bool bToolChanged = true ; if ( ! UpdateToolData( &bToolChanged)) { m_pMchMgr->SetLastError( 2401, "Error in Pocketing : UpdateToolData failed") ; return false ; } - // verifico se necessario continuare nell'aggiornamento + // verifico se necessario continuare nell'aggiornamento if ( ! bRecalc && ! bToolChanged && - ( m_nStatus == MCH_ST_OK || ( ! bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) { + ( m_nStatus == MCH_ST_OK || ( ! bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) { m_nPockets = nCurrPockets ; LOG_DBG_INFO( GetEMkLogger(), "Pocketing apply skipped : status already ok") ; return true ; } m_nStatus = MCH_ST_TO_VERIFY ; - // recupero gruppo per geometria ausiliaria + // 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) @@ -609,64 +609,67 @@ Pocketing::Apply( bool bRecalc, bool bPostApply) m_pGeomDB->SetStatus( nAuxId, GDB_ST_OFF) ; bChain = true ; } - // altrimenti, se chiesto ricalcolo, lo svuoto + // altrimenti, se chiesto ricalcolo, lo svuoto else if ( bRecalc) { m_pGeomDB->EmptyGroup( nAuxId) ; bChain = true ; } - // rendo corrente l'utensile usato nella lavorazione + // rendo corrente l'utensile usato nella lavorazione if ( ! m_pMchMgr->SetCalcTool( m_TParams.m_sName, m_TParams.m_sHead, m_TParams.m_nExit)) { m_pMchMgr->SetLastError( 2428, "Error in Pocketing : Tool loading failed") ; return false ; } - // recupero i dati del portautensile + // recupero i dati del portautensile int nToolId = m_pMchMgr->GetCalcTool() ; m_dTHoldLen = 0 ; m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ; m_dTHoldDiam = 0 ; m_pGeomDB->GetInfo( nToolId, TTH_DIAM, m_dTHoldDiam) ; - // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria if ( bChain && ! Chain( nAuxId)) { m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Chaining failed") ; return false ; } - // recupero gruppo per geometria di lavorazione (Cutter Location) + // 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) return false ; m_pGeomDB->SetName( nClId, MCH_CL) ; } - // altrimenti lo svuoto + // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nClId) ; - // lavoro ogni singola catena + // lavoro ogni singola catena bool bOk = true ; int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; - while ( nPathId != GDB_ID_NULL) { - if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) - bOk = false ; - nPathId = m_pGeomDB->GetNextGroup( nPathId) ; - } - if ( ! bOk) - return false ; + if ( ! ProcessPath2( nPathId, GDB_ID_NULL, nClId) ) + return false ; - // assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso + // while ( nPathId != GDB_ID_NULL) { + // if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) + // bOk = false ; + // nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + // } + // if ( ! bOk) + // return false ; + + // assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso CalcAndSetBBox( nClId) ; - // eseguo aggiornamento assi macchina e collegamento con operazione precedente + // eseguo aggiornamento assi macchina e collegamento con operazione precedente if ( ! Update( bPostApply)) return false ; - - // aggiorno stato della lavorazione + + // aggiorno stato della lavorazione m_nStatus = ( bPostApply ? MCH_ST_OK : MCH_ST_NO_POSTAPPL) ; - // dichiaro successiva da aggiornare + // dichiaro successiva da aggiornare UpdateFollowingOperationsStatus( MCH_ST_OTH_MODIF) ; return true ; @@ -676,17 +679,17 @@ 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 ; - // se lavorazione vuota, esco + // se lavorazione vuota, esco if ( m_nPockets == 0) { m_pMchMgr->SetWarning( 2452, "Warning in Pocketing : No machinable pocket") ; return true ; } - // imposto eventuale asse bloccato da lavorazione + // imposto eventuale asse bloccato da lavorazione if ( ! m_Params.m_sBlockedAxis.empty()) { string sAxis, sVal ; Split( m_Params.m_sBlockedAxis, "=", true, sAxis, sVal) ; @@ -696,7 +699,7 @@ Pocketing::Update( bool bPostApply) m_pMchMgr->SetRotAxisBlock( sAxis, dVal) ; } - // calcolo gli assi macchina + // calcolo gli assi macchina string sHint = ExtractHint( m_Params.m_sUserNotes) ; if ( ! m_Params.m_sInitAngs.empty()) sHint = m_Params.m_sInitAngs ; @@ -709,7 +712,7 @@ Pocketing::Update( bool bPostApply) return false ; } - // gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine della lavorazione + // gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine della lavorazione if ( ! AdjustStartEndMovements()) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) @@ -719,10 +722,10 @@ Pocketing::Update( bool bPostApply) return false ; } - // assegno estremi degli assi dei vari percorsi di lavorazione e della lavorazione nel suo complesso + // assegno estremi degli assi dei vari percorsi di lavorazione e della lavorazione nel suo complesso CalcAndSetAxesBBox() ; - // esecuzione eventuali personalizzazioni + // esecuzione eventuali personalizzazioni string sErr ; if ( bPostApply && ! PostApply( sErr)) { if ( ! IsEmptyOrSpaces( sErr)) @@ -876,32 +879,32 @@ Pocketing::GetToolData( void) const bool Pocketing::UpdateToolData( bool* pbChanged) { - // recupero il gestore DB utensili della macchina corrente + // recupero il gestore DB utensili della macchina corrente ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; if ( pTMgr == nullptr) return false ; - // recupero l'utensile nel DB utensili + // recupero l'utensile nel DB utensili const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) + // verifico se sono diversi (ad esclusione del nome) m_TParams.m_sName = pTdata->m_sName ; bool bChanged = ! SameTool( m_TParams, *pTdata) ; - // aggiorno comunque i parametri + // aggiorno comunque i parametri m_TParams = *pTdata ; - // eventuali segnalazioni + // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Pocketing : tool name changed (" + - m_Params.m_sToolName + "->" + m_TParams.m_sName + ")" ; + m_Params.m_sToolName + "->" + m_TParams.m_sName + ")" ; m_pMchMgr->SetWarning( 2453, sInfo) ; m_Params.m_sToolName = m_TParams.m_sName ; } if ( bChanged) { string sInfo = "Warning in Pocketing : tool data changed (" + - m_Params.m_sToolName + ")" ; + m_Params.m_sToolName + ")" ; m_pMchMgr->SetWarning( 2454, sInfo) ; } - // se definito parametro di ritorno, lo assegno + // se definito parametro di ritorno, lo assegno if ( pbChanged != nullptr) *pbChanged = bChanged ; return true ; @@ -910,8 +913,8 @@ 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 ; } @@ -920,15 +923,15 @@ Pocketing::GetGeometry( SELVECTOR& vIds) const bool Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) { - // ammessi : curve, testi, facce di trimesh o regioni + // ammessi : curve, testi, facce di trimesh o regioni 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 ; - // se direttamente la curva + // se direttamente la curva if ( Id.nSub == SEL_SUB_ALL) { pCurve = ::GetCurve( pGObj) ; if ( pCurve == nullptr) @@ -938,7 +941,7 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) else nSubs = 0 ; } - // altrimenti sottocurva di composita + // altrimenti sottocurva di composita else { const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; pCurve = ( pCompo != nullptr ? pCompo->GetCurve( Id.nSub) : nullptr) ; @@ -948,7 +951,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) ; @@ -957,7 +960,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) ; @@ -965,21 +968,21 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) return false ; // se direttamente la superficie if ( Id.nSub == SEL_SUB_ALL) { - // deve avere una sola faccia + // deve avere una sola faccia if ( pSurf->GetFacetCount() != 1) return false ; nSubs = 1 ; } // altrimenti faccia di superficie trimesh else { - // se faccia non esistente + // se faccia non esistente if ( Id.nSub >= pSurf->GetFacetCount()) return false ; nSubs = 0 ; } 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) ; @@ -991,15 +994,15 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) } // altrimenti chunk di regione else { - // se chunk non esistente + // se chunk non esistente if ( Id.nSub >= pReg->GetChunkCount()) return false ; - // tutto bene + // tutto bene nSubs = 0 ; } return true ; } - // altrimenti errore + // altrimenti errore else return false ; } @@ -1007,48 +1010,50 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType) //---------------------------------------------------------------------------- bool Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) -{ - // ammessi : curve, testi, facce di trimesh o regioni - const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; +{ + + LOG_ERROR( GetEMkLogger(), (" -- GET CURVES " + to_string( Id.nId) + " " + to_string( Id.nSub)).c_str()) + // ammessi : curve, testi, facce di trimesh o regioni + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; if ( pGObj == nullptr) return false ; - // ne recupero il riferimento globale + // ne recupero il riferimento globale Frame3d frGlob ; if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob)) return false ; - // se curva + // se curva if ( ( pGObj->GetType() & GEO_CURVE) != 0) { PtrOwner pCurve ; // se direttamente curva if ( Id.nSub == SEL_SUB_ALL) { - // recupero la curva + // recupero la curva const ICurve* pOriCurve = ::GetCurve( pGObj) ; if ( pOriCurve == nullptr) return false ; - // la duplico + // la duplico pCurve.Set( pOriCurve->Clone()) ; - // recupero eventuali informazioni per lati aperti + // recupero eventuali informazioni per lati aperti SetCurveAllTempProp( Id.nId, pCurve) ; - // se estrusione mancante, imposto default + // se estrusione mancante, imposto default Vector3d vtExtr ; if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall()) pCurve->SetExtrusion( Z_AX) ; } // altrimenti sottocurva di composita else { - // recupero la composita + // recupero la composita const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; if ( pCompo == nullptr) return false ; - // recupero la curva semplice + // recupero la curva semplice const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ; if ( pOriCurve == nullptr) return false ; - // la duplico + // la duplico pCurve.Set( pOriCurve->Clone()) ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCurve) ; - // recupero estrusione e spessore + // recupero estrusione e spessore Vector3d vtExtr ; if ( ! pCompo->GetExtrusion( vtExtr) || vtExtr.IsSmall()) vtExtr = Z_AX ; @@ -1059,131 +1064,140 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC) } if ( IsNull( pCurve)) return false ; - // la porto in globale + // la porto in globale pCurve->ToGlob( frGlob) ; - // la restituisco + // la restituisco lstPC.emplace_back( Release( pCurve)) ; return true ; } - // se altrimenti testo + // se altrimenti testo else if ( pGObj->GetType() == EXT_TEXT) { - // recupero il testo + // recupero il testo const IExtText* pText = ::GetExtText( pGObj) ; if ( pText == nullptr) return false ; - // recupero l'outline del testo + // 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 + // porto le curve in globale for ( auto pCrv : lstPC) pCrv->ToGlob( frGlob) ; - // ritorno + // ritorno return true ; } - // se altrimenti superficie + // se altrimenti superficie else if ( pGObj->GetType() == SRF_TRIMESH) { - // recupero la trimesh + // recupero la trimesh const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; if ( pSurf == nullptr) return false ; - // recupero l'indice della faccia + // recupero l'indice della faccia int nFacet = ( ( Id.nSub == SEL_SUB_ALL) ? 0 : Id.nSub) ; - // recupero i contorni della faccia + // recupero i contorni della faccia POLYLINEVECTOR vPL ; pSurf->GetFacetLoops( nFacet, vPL) ; if ( vPL.empty()) return false ; - // creo la curva a partire da quello esterno - PtrOwner pCrvCompo( CreateCurveComposite()) ; - pCrvCompo->FromPolyLine( vPL[0]) ; - if ( ! pCrvCompo->IsValid()) - return false ; - // reset proprietà temporanee - ResetCurveAllTempProp( pCrvCompo) ; - // 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 - 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) + // creo la curva a partire da quello esterno + for ( size_t k = 0 ; k < vPL.size() ; k++) { + + PtrOwner pCrvCompo( CreateCurveComposite()) ; + pCrvCompo->FromPolyLine( vPL[k]) ; + if ( ! pCrvCompo->IsValid()) + return false ; + + // reset proprietà temporanee + ResetCurveAllTempProp( pCrvCompo) ; + // determino eventuali lati aperti e aggiorno proprietà del contorno + int nInd = 0 ; + double dPar ; + bool bFound = vPL[k].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[k].GetNextU( dPar, true) ; } - // passo al successivo - ++ nInd ; - bFound = vPL[0].GetNextU( dPar, true) ; + // recupero la normale esterna della faccia + Vector3d vtN ; + if ( ! pSurf->GetFacetNormal( nFacet, vtN)) + return false ; + // 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) ; + for( size_t i = 0 ; i < pCrvCompo->GetCurveCount() ; i++){ + int val ; + pCrvCompo->GetCurveTempProp( i, val) ; + } + // la restituisco + lstPC.emplace_back( Release( pCrvCompo)) ; } - // recupero la normale esterna della faccia - Vector3d vtN ; - if ( ! pSurf->GetFacetNormal( nFacet, vtN)) - return false ; - // 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 ; } - // se altrimenti regione + // se altrimenti regione else if ( pGObj->GetType() == SRF_FLATRGN) { - // recupero la regione + // recupero la regione const ISurfFlatRegion* pReg = ::GetSurfFlatRegion( pGObj) ; if ( pReg == nullptr) return false ; - // recupero la normale della regione + // recupero la normale della regione Vector3d vtN = pReg->GetNormVersor() ; if ( vtN.IsSmall()) return false ; - // determino intervallo di chunk + // determino intervallo di chunk int nCstart = 0 ; int nCend = pReg->GetChunkCount() ; - if ( Id.nSub != SEL_SUB_ALL) { - nCstart = Id.nSub ; - nCend = nCstart + 1 ; - } - // ciclo sui chunk + // if ( Id.nSub != SEL_SUB_ALL) { + // nCstart = Id.nSub ; + // nCend = nCstart + 1 ; + // } + // ciclo sui chunk for ( int nC = nCstart ; nC < nCend ; ++ nC) { - // recupero i contorni del chunk + // 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))) return false ; - // reset proprietà temporanee + // reset proprietà temporanee ResetCurveAllTempProp( pCrvCompo) ; - // assegno l'estrusione dalla normale alla regione + // assegno l'estrusione dalla normale alla regione pCrvCompo->SetExtrusion( vtN) ; - // unisco le eventuali parti allineate + // unisco le eventuali parti allineate pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; - // la porto in globale + // la porto in globale pCrvCompo->ToGlob( frGlob) ; - // sistemazioni varie + // sistemazioni varie AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, 0) ; - // la restituisco + // la restituisco lstPC.emplace_back( Release( pCrvCompo)) ; } } return true ; } - // altrimenti errore + // altrimenti errore else return false ; } @@ -1194,21 +1208,21 @@ 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 + // verifico se presenti info per lati aperti if ( ! m_pGeomDB->ExistsInfo( nCrvId, KEY_OPEN)) return true ; - // recupero info sui lati aperti + // recupero info sui lati aperti INTVECTOR vOpen ; m_pGeomDB->GetInfo( nCrvId, KEY_OPEN, vOpen) ; - // se curva composita + // se curva composita ICurveComposite* pCC = GetCurveComposite( pCurve) ; if ( pCC != nullptr) { for ( int j : vOpen) pCC->SetCurveTempProp( j, 1) ; } - // altrimenti + // altrimenti else { if ( ! vOpen.empty() && vOpen[0] == 0) pCurve->SetTempProp( 1) ; @@ -1234,15 +1248,15 @@ Pocketing::ResetCurveAllTempProp( ICurve* pCurve) //---------------------------------------------------------------------------- bool Pocketing::Chain( int nGrpDestId) -{ - // vettore puntatori alle curve +{ + // vettore puntatori alle curve ICURVEPOVECTOR vpCrvs ; vpCrvs.reserve( m_vId.size()) ; - // vettore selettori delle curve originali + // vettore selettori delle curve originali SELVECTOR vInds ; - // recupero tutte le curve e le porto in globale - for ( const auto& Id : m_vId) { - // prendo le curve + // recupero tutte le curve e le porto in globale + for ( const auto& Id : m_vId) { + // prendo le curve ICURVEPLIST lstPC ; if ( ! GetCurves( Id, lstPC)) { string sInfo = "Warning in Pocketing : Skipped entity " + ToString( Id) ; @@ -1253,56 +1267,58 @@ Pocketing::Chain( int nGrpDestId) vInds.emplace_back( Id) ; } } - // preparo i dati per il concatenamento + // preparo i dati per il concatenamento bool bFirst = true ; Point3d ptNear = ORIG ; double dToler = 10 * EPS_SMALL ; ChainCurves chainC ; chainC.Init( true, dToler, int( vpCrvs.size())) ; for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) { - // recupero la curva e il suo riferimento + // recupero la curva e il suo riferimento ICurve* pCrv = vpCrvs[i] ; if ( pCrv == nullptr) continue ; - // recupero i dati della curva necessari al concatenamento e li assegno + + // recupero i dati della curva necessari al concatenamento e li assegno Point3d ptStart, ptEnd ; Vector3d vtStart, vtEnd ; if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) || - ! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd)) + ! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd)) return false ; if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd)) return false ; - // se prima curva, assegno inizio della ricerca + // se prima curva, assegno inizio della ricerca if ( bFirst) { ptNear = ptStart + 10 * EPS_SMALL * vtStart ; bFirst = false ; + } } - // recupero i percorsi concatenati + // recupero i percorsi concatenati int nCount = 0 ; INTVECTOR vnId2 ; while ( chainC.GetChainFromNear( ptNear, false, vnId2)) { - // creo una curva composita + // creo una curva composita PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo)) return false ; - // estrusione e spessore + // estrusione e spessore Vector3d vtExtr = Z_AX ; double dThick = 0 ; - // vettore Id originali + // vettore Id originali SELVECTOR vId2 ; vId2.reserve( vnId2.size()) ; - // recupero le curve semplici e le inserisco nella curva composita + // recupero le curve semplici e le inserisco nella curva composita for ( size_t i = 0 ; i < vnId2.size() ; ++ i) { int nId = abs( vnId2[i]) - 1 ; bool bInvert = ( vnId2[i] < 0) ; vId2.emplace_back( vInds[nId]) ; - // recupero la curva + // recupero la curva ICurve* pCrv = vpCrvs[nId] ; - // se necessario, la inverto + // se necessario, la inverto if ( bInvert) pCrv->Invert() ; - // recupero eventuali estrusione e spessore + // recupero eventuali estrusione e spessore Vector3d vtTemp ; if ( pCrv->GetExtrusion( vtTemp)) { vtExtr = vtTemp ; @@ -1310,39 +1326,41 @@ Pocketing::Chain( int nGrpDestId) if ( pCrv->GetThickness( dTemp) && abs( dTemp) > abs( dThick)) dThick = dTemp ; } - // la aggiungo alla curva composta + // la aggiungo alla curva composta if ( ! pCrvCompo->AddCurve( ::Release( vpCrvs[nId]), true, dToler)) return false ; } - // se non sono state inserite curve, vado oltre + // se non sono state inserite curve, vado oltre if ( pCrvCompo->GetCurveCount() == 0) continue ; - // imposto estrusione e spessore + // imposto estrusione e spessore pCrvCompo->SetExtrusion( vtExtr) ; pCrvCompo->SetThickness( dThick) ; - // aggiorno il nuovo punto vicino + // aggiorno il nuovo punto vicino pCrvCompo->GetEndPoint( ptNear) ; - // se utile, approssimo con archi + // se utile, approssimo con archi if ( ! ApproxWithArcsIfUseful( pCrvCompo, true)) return false ; - // recupero eventuali lati aperti + // recupero eventuali lati aperti INTVECTOR vOpen ; for ( int i = 0 ; i < int( pCrvCompo->GetCurveCount()) ; ++ i) { int nProp = 0 ; if ( pCrvCompo->GetCurveTempProp( i, nProp) && nProp == 1) vOpen.emplace_back( i) ; } - // creo nuovo gruppo + // 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)) ; + string s ; + m_pGeomDB->GetName(nPathId, s) ; m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( vId2)) ; - // inserisco la curva composita nel gruppo destinazione + // 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 + // salvo info con eventuali lati aperti if ( ! vOpen.empty()) m_pGeomDB->SetInfo( nNewId, KEY_OPEN, vOpen) ; } @@ -1351,76 +1369,482 @@ Pocketing::Chain( int nGrpDestId) //---------------------------------------------------------------------------- bool -Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) -{ - // recupero gruppo per geometria temporanea +Pocketing::ProcessPath2( int nPathId, int nPvId, int nClId) +{ + // 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) + return false ; + m_pGeomDB->SetName( nTempId, GRP_TEMP) ; + + } + // altrimenti lo svuoto + else + m_pGeomDB->EmptyGroup( nTempId) ; + // in ogni caso lo dichiaro temporaneo e non visibile + m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; + m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; + + + // analizzo tutti i path nel gruppo aux + int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; + int nPId = m_pGeomDB->GetFirstInGroup( nAuxId) ; + if ( nPId == GDB_ID_NULL) + return false ; + + // Costruisco la flat region definita dalle curve selezionate + // cerco la curva che definisce il loop esterno della superficie e verifico che le altre curve siano contenute al suo interno + std::vector< std::pair> vIdxArea ; // vettore di coppie indice curva, area + while ( nPId != GDB_ID_NULL) { + int nCrvId = m_pGeomDB->GetFirstInGroup( nPId) ; + if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) + return false ; + ICurve* pCrv = ::GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; + if ( pCrv == nullptr) + return false ; + + Plane3d plPlane ; double dArea ; + if ( ! pCrv->GetArea( plPlane, dArea)) + return false ; + vIdxArea.emplace_back( nCrvId, dArea) ; + + // passo al path succesivo + nPId = m_pGeomDB->GetNextGroup( nPId) ; + } + + // ordino in senso decrescente sull'area + sort( vIdxArea.begin(), vIdxArea.end(), + []( const std::pair& a, const std::pair& b) { return ( abs( a.second) > abs( b.second)) ; }) ; + // identifico il loop esterno come il loop di area maggiore + const ICurveComposite * pCompoExtTmp = GetCurveComposite( m_pGeomDB->GetGeoObj( vIdxArea[0].first)) ; + ISurfFlatRegion * pSrfTmp = CreateSurfFlatRegion() ; + if ( pSrfTmp == nullptr || ! pSrfTmp->AddExtLoop( pCompoExtTmp->Clone())) + return false ; + + // verifico che contenga tutte le altre curve che rappresentano i loop interni + for ( auto it = vIdxArea.begin() + 1 ; it != vIdxArea.end() ; it ++ ) { + + CRVCVECTOR ccClass ; + ICurve * pCrv = ::GetCurve( m_pGeomDB->GetGeoObj( it->first)) ; + if ( ! pSrfTmp->GetCurveClassification( *pCrv, ccClass)) + return false ; + + // se una curva non è completamente contenuta la ignoro + if ( ccClass.size() != 1 || ccClass[0].nClass != CRVC_IN) { + m_pMchMgr->SetWarning( 2413, "Warining in Pocketing : curve " + to_string( it->first) + " is ignored") ; + vIdxArea.erase( it) ; + it -- ; + } + } + + Vector3d vtExtr = Z_AX ; + double dThick = 0.0 ; + + double dRbDist ; + double dElev ; + double dDepth ; + Vector3d vtTool ; + BBox3d b3Raw ; + INTVECTOR vCopyIds ; + + // analizzo tutti i path + for( size_t i = 0 ; i < vIdxArea.size() ; i++ ) { + int nCrvId = vIdxArea[i].first ; + ICurve* pCrv = ::GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; + + // verifico sia una curva chiusa (deve delimitare l'area da svuotare) + if ( pCrv == nullptr || ! pCrv->IsClosed()) { + m_pMchMgr->SetLastError( 2402, "Error in Pocketing : Open Contour") ; + return false ; + } + + // copio la curva composita da elaborare + int nCopyId = m_pGeomDB->CopyGlob( nCrvId, GDB_ID_NULL, nTempId) ; + if ( nCopyId == GDB_ID_NULL) + return false ; + + vCopyIds.push_back( nCopyId) ; + ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ; + + // aggiorno flag per lati aperti + bool bSomeOpen = m_pGeomDB->ExistsInfo( nCrvId, KEY_OPEN) ; + if ( bSomeOpen) { + for ( int i = 0 ; i < int( pCompo->GetCurveCount()) ; ++ i) + pCompo->SetCurveTempProp( i, 0) ; + INTVECTOR vOpen ; + m_pGeomDB->GetInfo( nCrvId, KEY_OPEN, vOpen) ; + for ( int j : vOpen) + pCompo->SetCurveTempProp( j, 1) ; + } + + // recupero estrusione e spessore + Vector3d vtExtrCrv = Z_AX ; + double dThickCrv ; + pCompo->GetExtrusion( vtExtrCrv) ; + pCompo->GetThickness( dThickCrv) ; + + // eventuale inversione direzione utensile + if ( m_Params.m_bToolInvert) { + vtExtrCrv.Invert() ; + pCompo->SetExtrusion( vtExtrCrv) ; + dThickCrv = - dThick ; + pCompo->SetThickness( dThickCrv) ; + } + + // 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( vtExtrCrv) ; + pCompo->Clear() ; + pCompo->AddCurve( Release( pFlatCrv)) ; + pCompo->SetExtrusion( vtExtrCrv) ; + pCompo->SetThickness( dThickCrv) ; + LOG_ERROR( GetEMkLogger(), (" dThick " + to_string( dThickCrv)).c_str()) ; + + // Prendo come vtExtr e dThick di riferimento quelle della prima curva + if ( i == 0) { + vtExtr = vtExtrCrv ; + dThick = dThickCrv ; + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; + string sMyDepth = m_Params.m_sDepth ; + if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) { + m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ; + return false ; + } + + // se spessore positivo, lo sottraggo dal risultato + if ( dThick > 0) + dDepth -= dThick ; + // sottraggo eventuale offset longitudinale + dDepth -= GetOffsL() ; + // assegno il versore fresa + vtTool = vtExtr ; + } + else { + if ( ! AreSameVectorApprox( vtExtr, vtExtrCrv)) + return false ; + if ( abs( dThick - dThickCrv ) > EPS_SMALL) + return false ; + } + + // unisco le parti allineate (tranne inizio-fine se chiusa) + if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false, true)) + return false ; + + // recupero distanza da fondo dei grezzi interessati dal percorso + double dRbDist2 = 0 ; + if ( AreSameVectorApprox( vtExtr, Z_AX)) { + if ( ! GetDistanceFromRawBottom( m_nPhase, nCopyId, m_TParams.m_dTDiam, dRbDist2)) + return false ; + } + if ( i == 0) { + dRbDist = dRbDist2 ; + ExeLuaSetGlobNumVar( "RB", dRbDist) ; + } + else { + if ( abs( dRbDist - dRbDist2 ) > EPS_SMALL) + return false ; + } + + // recupero il box del grezzo in globale + if ( i == 0) { + 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 ; + } + } + + // calcolo l'elevazione massima + double dElev2 ; + if ( CalcRegionElevation( pCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dElev2)) { + if ( dElev2 < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { + BBox3d b3Crv ; + pCompo->GetLocalBBox( b3Crv) ; + dElev2 = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min( 0., dThick) + dDepth) ; + } + } + else + return false ; + if ( i == 0 ) + dElev = dElev2 ; + else { + if ( abs( dElev - dElev2) > EPS_SMALL) + return false ; + } + + } + // end while + // + // sistemo senso antiorario visto dalla direzione di estrusione per curva più esterna + ICurveComposite * pCompoExt = GetCurveComposite( m_pGeomDB->GetGeoObj( vCopyIds[0])) ; + Plane3d plPlane ; double dArea ; + pCompoExt->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) { + pCompoExt->Invert() ; + } + + // gestione lati aperti per la curva più esterna + bool bMidOpen = false ; + Point3d ptMidOpen ; + Vector3d vtMidOut ; + bool bSomeOpen = m_pGeomDB->ExistsInfo( vCopyIds[0], KEY_OPEN) ; + if ( bSomeOpen) { + // ricerca del punto medio del lato aperto più lungo + bMidOpen = GetMidOfLongestOpenSide( pCompoExt, ptMidOpen, vtMidOut) ; + // sistemazioni per eventuali lati aperti + if ( ! AdjustContourWithOpenEdges( pCompoExt)) { + 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, *pCompoExt).GetParamAtMinDistPoint( 0, dPar, nFlag) && pCompoExt->ChangeStartPoint( dPar)) ; + } + if ( ! bMidOpen) + AdjustContourStart( pCompoExt) ; + + Point3d ptStart ; pCompoExt->GetStartPoint( ptStart) ; + + // if ( m_Params.m_bToolInvert) { + // vtExtrCrv.Invert() ; + // pCompo->SetExtrusion( vtExtrCrv) ; + // dThickCrv = - dThick ; + // pCompo->SetThickness( dThickCrv) ; + // } + + // recupero nome del path + string sPathName ; + m_pGeomDB->GetName( nPathId, sPathName) ; + + + // eventuale imposizione massima elevazione da note utente + double 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) ; + 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) ; + dDepth -= dElev - m_TParams.m_dMaxMat ; + dElev = m_TParams.m_dMaxMat ; + } + } + // altrimenti lavorazione a step + else { + // 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 ? 0 : m_dTHoldLen) - dSafe ; + if ( dElev > dMaxDepth + EPS_SMALL) { + // segnalo, riduco e continuo + string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ; + m_pMchMgr->SetWarning( 2458, sInfo) ; + dDepth -= dElev - dMaxDepth ; + dElev = dMaxDepth ; + } + } + + // verifico se tavola basculante + bool bTiltTab = false ; + 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( pCompoExt, vtTool)) { + return false ; + } + + // // se richiesta anteprima + // if ( nPvId != GDB_ID_NULL) { + // // creo gruppo per geometria di lavorazione del percorso + // int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; + // if ( nPxId == GDB_ID_NULL) + // return false ; + // m_pGeomDB->SetName( nPxId, sPathName) ; + // m_pGeomDB->SetMaterial( nPxId, GREEN) ; + // // creo l'anteprima del percorso + // if ( ! GeneratePocketingPv( nPxId, pCompo)) + // return false ; + // } + + // se richiesta lavorazione + if ( nClId != GDB_ID_NULL) { + // creo gruppo per geometria di lavorazione del percorso + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + + // 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())) ; + + // 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, ptStart) ; + m_pGeomDB->SetInfo( nPxId, KEY_END, ptStart) ; + // assegno l'elevazione massima + m_pGeomDB->SetInfo( nPxId, KEY_ELEV, dElev) ; + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + + + // Creo una SurfFlatRegion a partire dalle curve in Temp + int pnCount ; + int nSrfId = ExeCreateSurfFlatRegion( nTempId, vCopyIds, &pnCount) ; + if ( nSrfId == GDB_ID_NULL) + return false ; + + ISurfFlatRegion * pSrf = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( nSrfId)) ; + if ( pSrf == nullptr) + return false ; + + // Eseguo la lavorazione a seconda del tipo + switch ( m_Params.m_nSubType) { + case POCKET_SUB_ZIGZAG : + if ( ! AddZigZag( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + return false ; + break ; + case POCKET_SUB_ONEWAY : + if ( ! AddOneWay( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + return false ; + break ; + case POCKET_SUB_SPIRALIN : + if ( ! AddSpiralIn( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, bMidOpen, ptMidOpen, vtMidOut)) + return false ; + break ; + case POCKET_SUB_SPIRALOUT : + if ( ! AddSpiralOut( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + return false ; + break ; + } + } + + // incremento numero di svuotature + ++ m_nPockets ; + return true ; +} + + +//---------------------------------------------------------------------------- +bool +Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) +{ + // recupero gruppo per geometria temporanea + const string GRP_TEMP = "Temp" ; + int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; + // 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) return false ; m_pGeomDB->SetName( nTempId, GRP_TEMP) ; } - // altrimenti lo svuoto + // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nTempId) ; - // in ogni caso lo dichiaro temporaneo e non visibile + // in ogni caso lo dichiaro temporaneo e non visibile m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; - // verifico sia una curva chiusa (deve delimitare l'area da svuotare) + // verifico sia una curva chiusa (deve delimitare l'area da svuotare) int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; - if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) + if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) { return false ; + } + ICurve* pCrv = ::GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr || ! pCrv->IsClosed()) { m_pMchMgr->SetLastError( 2402, "Error in Pocketing : Open Contour") ; return false ; } - - // copio la curva composita da elaborare + // 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 + // aggiorno flag per 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) { + for ( int i = 0 ; i < int( pCompo->GetCurveCount()) ; ++ i) + pCompo->SetCurveTempProp( i, 0) ; INTVECTOR vOpen ; m_pGeomDB->GetInfo( nCrvId, KEY_OPEN, vOpen) ; for ( int j : vOpen) pCompo->SetCurveTempProp( j, 1) ; } - - // recupero estrusione e spessore + // recupero estrusione e spessore Vector3d vtExtr = Z_AX ; pCompo->GetExtrusion( vtExtr) ; double dThick ; pCompo->GetThickness( dThick) ; - // eventuale inversione direzione utensile + // eventuale inversione direzione utensile if ( m_Params.m_bToolInvert) { vtExtr.Invert() ; pCompo->SetExtrusion( vtExtr) ; dThick = - dThick ; pCompo->SetThickness( dThick) ; } - - // verifico sia piana e se necessario la appiattisco + // 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 ; @@ -1435,31 +1859,30 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) pCompo->AddCurve( Release( pFlatCrv)) ; pCompo->SetExtrusion( vtExtr) ; pCompo->SetThickness( dThick) ; - // sistemo senso antiorario visto dalla direzione di estrusione + // 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) + // 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 + // se ci sono lati aperti bool bMidOpen = false ; Point3d ptMidOpen ; Vector3d vtMidOut ; if ( bSomeOpen) { - // ricerca del punto medio del lato aperto più lungo + // ricerca del punto medio del lato aperto più lungo bMidOpen = GetMidOfLongestOpenSide( pCompo, ptMidOpen, vtMidOut) ; - // sistemazioni per eventuali lati aperti + // 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) + // sposto l'inizio a metà del tratto più lungo ( o aperto più lungo) if ( bMidOpen) { const double LEN_OUT = 5 ; double dPar ; int nFlag ; @@ -1468,24 +1891,23 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) if ( ! bMidOpen) AdjustContourStart( pCompo) ; - // recupero il punto di inizio (per poi salvarlo nelle info di CL path) + // 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 + // recupero il box del grezzo in globale BBox3d b3Raw ; 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 + // recupero distanza da fondo dei grezzi interessati dal percorso double dRbDist = 0 ; if ( AreSameVectorApprox( vtExtr, Z_AX)) { if ( ! GetDistanceFromRawBottom( m_nPhase, nCopyId, m_TParams.m_dTDiam, dRbDist)) return false ; } - // valuto l'espressione dell'affondamento + // valuto l'espressione dell'affondamento ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; ExeLuaSetGlobNumVar( "RB", dRbDist) ; double dDepth ; @@ -1494,20 +1916,19 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ; return false ; } - // se spessore positivo, lo sottraggo dal risultato + // se spessore positivo, lo sottraggo dal risultato if ( dThick > 0) dDepth -= dThick ; - // sottraggo eventuale offset longitudinale + // sottraggo eventuale offset longitudinale dDepth -= GetOffsL() ; - // recupero nome del path + // recupero nome del path string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; - // assegno il versore fresa + // assegno il versore fresa Vector3d vtTool = vtExtr ; - - // calcolo l'elevazione massima + // calcolo l'elevazione massima double dElev ; if ( CalcRegionElevation( pCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dElev)) { if ( dElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { @@ -1518,163 +1939,196 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) } else return false ; - // eventuale imposizione massima elevazione da note utente + // eventuale imposizione massima elevazione da note utente double dMaxElev ; if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) dElev = dMaxElev ; - // verifico che lo step dell'utensile sia sensato + // 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) + ")" ; + ToString( m_Params.m_dStep, 2) + ")" ; m_pMchMgr->SetWarning( 2456, sInfo) ; } - // verifico che il massimo materiale dell'utensile sia sensato + // 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) + ")" ; + ToString( m_TParams.m_dMaxMat, 2) + ")" ; m_pMchMgr->SetLastError( 2422, sInfo) ; return false ; } - // verifico di non superare il massimo materiale + // 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) + ")" ; + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; m_pMchMgr->SetWarning( 2457, sInfo) ; } - // se lavorazione singola + // se lavorazione singola if ( dOkStep < EPS_SMALL || dOkStep > dElev) { - // se l'elevazione supera la capacità dell'utensile + // 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) + ")" ; + ") 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 ? 0 : 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 ; } } - // verifico se tavola basculante + // verifico se tavola basculante bool bTiltTab = false ; m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ; - // verifico se testa da sopra (Z+) + // verifico se testa da sopra (Z+) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; - // verifiche per svuotature dal basso + // verifiche per svuotature dal basso m_bAggrBottom = false ; if ( ! VerifyPathFromBottom( pCompo, vtTool)) { return false ; } - // se richiesta anteprima + // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { - // creo gruppo per geometria di lavorazione del percorso + // creo gruppo per geometria di lavorazione del percorso int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; if ( nPxId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nPxId, sPathName) ; m_pGeomDB->SetMaterial( nPxId, GREEN) ; - // creo l'anteprima del percorso + // creo l'anteprima del percorso if ( ! GeneratePocketingPv( nPxId, pCompo)) return false ; } - // se richiesta lavorazione + // se richiesta lavorazione if ( nClId != GDB_ID_NULL) { - // creo gruppo per geometria di lavorazione del percorso + // creo gruppo per geometria di lavorazione del percorso int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; if ( nPxId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nPxId, sPathName) ; m_pGeomDB->SetMaterial( nPxId, BLUE) ; - // verifico se archi vanno approssimati con segmenti di retta + // 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())) ; + ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtExtr.IsZplus()) || + ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ; - // assegno il vettore estrazione al gruppo del percorso + // 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 + // assegno i punti di inizio e fine al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_START, ptStart) ; m_pGeomDB->SetInfo( nPxId, KEY_END, ptStart) ; - // assegno l'elevazione massima + // assegno l'elevazione massima m_pGeomDB->SetInfo( nPxId, KEY_ELEV, dElev) ; - // Imposto dati comuni + // Imposto dati comuni SetPathId( nPxId) ; SetToolDir( vtTool) ; - // Eseguo la lavorazione a seconda del tipo + LOG_ERROR( GetEMkLogger(), (" dRibdist " + to_string( dRbDist) + " dElev " + to_string( dElev)).c_str()) ; + // Creo una SurfFlatRegion a partire dalle curve in Temp + int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ; + int nPId = m_pGeomDB->GetFirstInGroup( nAuxId) ; + INTVECTOR vCopyIds ; + while ( nPId != GDB_ID_NULL) { + vCopyIds.push_back( m_pGeomDB->CopyGlob( nPId + 1, GDB_ID_NULL, nTempId)) ; + nPId = m_pGeomDB->GetNextGroup( nPId) ; + } + + DBLVECTOR vArea ; + for ( size_t i = 0 ; i < vCopyIds.size() ; i++) { + Plane3d plPlane ; double dArea ; + ICurveComposite * pCmp = GetCurveComposite( m_pGeomDB->GetGeoObj( vCopyIds[i])) ; + if ( ! pCmp->GetArea( plPlane, dArea)) + return false ; + vArea.emplace_back( dArea) ; + } + DBLVECTOR::iterator it = max_element( vArea.begin(), vArea.end()) ; + size_t idx = it - vArea.begin() ; + ICurveComposite * pCmp = GetCurveComposite( m_pGeomDB->GetGeoObj( vCopyIds[idx])) ; + Plane3d plPlane ; double dArea ; + pCmp->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) { + pCmp->Invert() ; + } + + int pnCount ; + int nSrfId = ExeCreateSurfFlatRegion( nTempId, vCopyIds, &pnCount) ; + ISurfFlatRegion * pSrf = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( nSrfId)) ; + + + // Eseguo la lavorazione a seconda del tipo switch ( m_Params.m_nSubType) { case POCKET_SUB_ZIGZAG : - if ( ! AddZigZag( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + if ( ! AddZigZag( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) return false ; break ; case POCKET_SUB_ONEWAY : - if ( ! AddOneWay( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + if ( ! AddOneWay( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) return false ; break ; case POCKET_SUB_SPIRALIN : - if ( ! AddSpiralIn( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, bMidOpen, ptMidOpen, vtMidOut)) + if ( ! AddSpiralIn( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs, bMidOpen, ptMidOpen, vtMidOut)) return false ; break ; case POCKET_SUB_SPIRALOUT : - if ( ! AddSpiralOut( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) + if ( ! AddSpiralOut( pSrf, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) return false ; break ; } } - // incremento numero di svuotature + // incremento numero di svuotature ++ m_nPockets ; return true ; } + //---------------------------------------------------------------------------- bool Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, - double& dElev) const -{ - // inizializzo l'elevazione + double& dElev) const +{ + // inizializzo l'elevazione dElev = 0 ; - // affondamento come vettore + // affondamento come vettore Vector3d vtDepth = vtTool * dDepth ; - // Campiono il contorno + // Campiono il contorno int nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente + // curva corrente const ICurve* pCrvC = pCompo->GetCurve( i) ; Point3d ptStart ; pCrvC->GetStartPoint( ptStart) ; Point3d ptMid ; pCrvC->GetMidPoint( ptMid) ; Point3d ptEnd ; pCrvC->GetEndPoint( ptEnd) ; - // elevazione della curva + // elevazione della curva double dCurrElev ; if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { if ( dCurrElev > dElev) @@ -1686,7 +2140,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v } } - // Campiono l'interno con una griglia (uso linee parallele a X) + // Campiono l'interno con una griglia (uso linee parallele a X) // determino il riferimento di base Frame3d frPocket ; Point3d ptCen ; pCompo->GetCentroid( ptCen) ; @@ -1700,7 +2154,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v // ingombro del contorno in locale BBox3d b3Pocket ; pCompoL->GetLocalBBox( b3Pocket) ; - Point3d ptMin ; double dDimX, dDimY, dDimZ ; + Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; // passi in Y const double STEP = 50 ; @@ -1709,7 +2163,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v // calcolo le linee di svuotatura int nCount = 0 ; for ( int i = 1 ; i < nYStep ; ++ i) { - // definisco la linea + // 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) ; @@ -1717,11 +2171,12 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; return false ; } - // calcolo la classificazione della curva rispetto al contorno + + // calcolo la classificazione della curva rispetto al contorno IntersCurveCurve intCC( *pLine, *pCompoL) ; - CRVCVECTOR ccClass ; + CRVCVECTOR ccClass ; if ( intCC.GetCurveClassification( 0, ccClass)) { - // determino gli intervalli di curva interni + // determino gli intervalli di curva interni Intervals inOk ; for ( auto& ccOne : ccClass) { if ( ccOne.nClass == CRVC_IN) { @@ -1731,7 +2186,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v Point3d ptEnd ; pLine->GetPointD1D2( ccOne.dParE, ICurve::FROM_MINUS, ptEnd) ; ptEnd.ToGlob( frPocket) ; - // elevazione della curva + // elevazione della curva double dCurrElev ; if ( GetElevation( m_nPhase, ptStart - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { if ( dCurrElev > dElev) @@ -1744,7 +2199,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v } } } - // altrimenti uso tutta la curva + // altrimenti uso tutta la curva else { Point3d ptStart ; pLine->GetStartPoint( ptStart) ; @@ -1752,7 +2207,7 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v Point3d ptEnd ; pLine->GetEndPoint( ptEnd) ; ptEnd.ToGlob( frPocket) ; - // elevazione della curva + // elevazione della curva double dCurrElev ; if ( GetElevation( m_nPhase, ptStart - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { if ( dCurrElev > dElev) @@ -1772,25 +2227,25 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v bool 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 + // recupero dati di eventuale rinvio da sotto if ( ! GetAggrBottomData( m_TParams.m_sHead, m_AggrBottom) || m_AggrBottom.nType == 0) { m_pMchMgr->SetLastError( 2409, "Error in Pocketing : missing aggregate from bottom") ; return false ; } - // calcolo la massima distanza minima del percorso dal contorno del grezzo + // calcolo la massima distanza minima del percorso dal contorno del grezzo double dDist = 0 ; Vector3d vtDir ; int nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente + // curva corrente const ICurve* pCrvC = pCompo->GetCurve( i) ; - // considero inizio della prima curva, punto medio e fine di tutte + // considero inizio della prima curva, punto medio e fine di tutte Point3d ptP ; double dCurrDist = 0 ; Vector3d vtCurrDir ; @@ -1815,12 +2270,12 @@ Pocketing::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtDir = vtCurrDir ; } } - // se supera il limite, errore + // se supera il limite, errore if ( dDist > m_AggrBottom.dDMax) { m_pMchMgr->SetLastError( 2410, "Error in Pocketing : path too far from part sides") ; return false ; } - // assegno direzione di accesso e segnalo utilizzo aggregato da sotto + // assegno direzione di accesso e segnalo utilizzo aggregato da sotto m_vtAggrBottom = vtDir ; m_bAggrBottom = true ; return true ; @@ -1830,16 +2285,16 @@ Pocketing::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& bool Pocketing::GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) { - // creo copia della curva composita + // creo copia della curva composita PtrOwner< ICurve> pCrv( pCompo->Clone()) ; if ( IsNull( pCrv)) return false ; - // calcolo la regione + // calcolo la regione PtrOwner pSfr ; pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), 0.5 * m_TParams.m_dDiam, false, false)) ; if ( IsNull( pSfr)) return false ; - // ne recupero il contorno + // ne recupero il contorno PtrOwner< ICurve> pCrv2 ; pCrv2.Set( pSfr->GetLoop( 0, 0)) ; if ( IsNull( pCrv2)) @@ -1851,28 +2306,28 @@ Pocketing::GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) // assegno nome e colore m_pGeomDB->SetName( nC2Id, MCH_PV_CUT) ; m_pGeomDB->SetMaterial( nC2Id, LIME) ; - // eventuali altri contorni ( interni di contornatura chiusa) + // eventuali altri contorni ( interni di contornatura chiusa) const int MAX_INT_LOOP = 1000 ; for ( int i = 1 ; i <= MAX_INT_LOOP ; ++i) { PtrOwner< ICurve> pCrv3 ; pCrv3.Set( pSfr->GetLoop( 0, i)) ; if ( IsNull( pCrv3)) break ; - // inserisco la curva nel DB + // inserisco la curva nel DB int nC3Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv3)) ; if ( nC3Id == GDB_ID_NULL) return false ; - // assegno nome e colore + // assegno nome e colore m_pGeomDB->SetName( nC3Id, MCH_PV_CUT) ; m_pGeomDB->SetMaterial( nC3Id, LIME) ; } - // inserisco la regione nel DB + // inserisco la regione nel DB int nRId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfr)) ; if ( nRId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nRId, MCH_PV_RCUT) ; m_pGeomDB->SetMaterial( nRId, INVISIBLE) ; - // la copio anche come regione ridotta + // la copio anche come regione ridotta int nRrId = m_pGeomDB->Copy( nRId, GDB_ID_NULL, nPathId) ; if ( nRrId == GDB_ID_NULL) return false ; @@ -1898,71 +2353,77 @@ GetCurveRadius( const ICurve* pCrv) //---------------------------------------------------------------------------- bool -Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) -{ - // recupero distanze di sicurezza +Pocketing::AddZigZag( const ISurfFlatRegion* pSrf, 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 + // 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) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } - // determino numero e affondamento degli step + // determino numero e affondamento degli step int nStep = 1 ; nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; double dStep = dElev / nStep ; - // calcolo curva offsettata del raggio utensile + sovramateriale + (se non lucidatura) extra + // calcolo superficie offsettata del raggio utensile + sovramateriale + (se non lucidatura) extra double dTRad = 0.5 * m_TParams.m_dDiam ; double dOffs = dTRad + GetOffsR() ; double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCompo, - ( dOffs + dExtra), ICurve::OFF_FILLET)) { + PtrOwner pSrfOff1( pSrf->Clone()) ; + if ( IsNull( pSrfOff1)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + if ( ! pSrfOff1->Offset( - ( dOffs + dExtra), ICurve::OFF_FILLET) || ! pSrfOff1->IsValid()) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } - // ciclo sulle curve risultanti + // ciclo sulle superfici risultanti bool bStart = true ; - while ( OffsCrv.GetCurveCount() > 0) { + Point3d ptOld ; + int nChunks = pSrfOff1->GetChunkCount() ; + int nC = 0 ; - // 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") ; + while ( nC != nChunks) { + + // recupero la prima regione di offset + PtrOwner pSrfChunk( pSrfOff1->CloneChunk( nC)) ; + if ( IsNull( pSrfChunk)) return false ; - } - // determino il riferimento di base e il box della svuotatura + // determino il riferimento di base e il box della svuotatura Frame3d frPocket ; - Point3d ptCen ; pCompo->GetCentroid( ptCen) ; + Point3d ptCen ; pSrfChunk->GetChunkCentroid( 0, ptCen) ; frPocket.Set( ptCen, vtExtr) ; frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pOffs->ToLoc( frPocket) ; + pSrfChunk->ToLoc( frPocket) ; - // calcolo i percorsi di svuotatura + // calcolo i percorsi di svuotatura ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcZigZag( pOffs, vpCrvs)) + if ( ! CalcZigZag( pSrfChunk, vpCrvs)) return false ; - // se richiesta inversione + // se richiesta inversione if ( m_Params.m_bInvert) { - // ciclo sui percorsi + // ciclo sui percorsi for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) vpCrvs[k]->Invert() ; } - // se lucidatura + // se lucidatura if ( m_TParams.m_nType == TT_MILL_POLISHING) { - // ciclo sui percorsi + // ciclo sui percorsi for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { - // se attacco a scivolo + // se attacco a scivolo if ( GetLeadInType() == POCKET_LI_GLIDE) { double dU ; vpCrvs[k]->GetParamAtLength( m_Params.m_dLiTang, dU) ; @@ -1971,7 +2432,7 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con vpCrvs[k]->GetStartPoint( ptStart) ; vpCrvs[k]->ModifyStart( ptStart + vtTool * m_Params.m_dLiElev) ; } - // se uscita a scivolo + // se uscita a scivolo if ( GetLeadOutType() == POCKET_LO_GLIDE) { double dLen, dU ; vpCrvs[k]->GetLength( dLen) ; @@ -1984,43 +2445,43 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con } } - // inserisco i movimenti di svuotatura + // inserisco i movimenti di svuotatura for ( int j = 1 ; j <= nStep ; ++ j) { - // ciclo sui percorsi + // ciclo sui percorsi for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { - // ciclo sulle curve elementari + // ciclo sulle curve elementari int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente + // curva corrente const ICurve* pCrvC = vpCrvs[k]->GetCurve( i) ; - // copio la curva + // copio la curva PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; pCurve->ToGlob( frPocket) ; - // aggiungo affondamento + // aggiungo affondamento pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // se prima entità + // se prima entità if ( i == 0 ) { - // dati inizio entità + // dati inizio entità Point3d ptStart ; pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // determino inizio attacco + // determino inizio attacco Point3d ptP1 ; if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1)) return false ; - // determino elevazione su inizio attacco + // determino elevazione su inizio attacco double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; if ( bUnderStart) dStElev = max( dStElev, dElev) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se inizio, approccio globale al punto iniziale + // se inizio, approccio globale al punto iniziale if ( bStart) { if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) { m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; @@ -2028,21 +2489,21 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con } bStart = false ; } - // altrimenti, approccio di collegamento + // altrimenti, approccio di collegamento else { if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; } } - // aggiungo attacco + // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs, true)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs, true)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } } - // elaborazioni sulla curva corrente + // elaborazioni sulla curva corrente if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; Point3d ptP3 = pLine->GetEnd() ; @@ -2061,14 +2522,14 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; } - // se ultima entità + // se ultima entità if ( i == nMaxInd) { - // dati fine entità + // dati fine entità Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita + // aggiungo uscita double dEndElev = dElev ; Point3d ptP1 ; SetFeed( GetEndFeed()) ; @@ -2076,14 +2537,14 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - // se lucidatura e ultimo step, aggiungo retrazione + // se lucidatura e ultimo step, aggiungo retrazione if ( m_TParams.m_nType == TT_MILL_POLISHING && 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 + // altrimenti, aggiungo retrazione di collegamento else { if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; @@ -2094,248 +2555,298 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con } } } + + nC ++ ; } - // se lucidatura, non aggiungo contorno + // se lucidatura, non aggiungo contorno if ( m_TParams.m_nType == TT_MILL_POLISHING) - return true ; + return true ; - // calcolo seconda curva offsettata del raggio utensile + sovramateriale - OffsetCurve OffsCrv2 ; - if ( ! OffsCrv2.Make( pCompo, - dOffs, ICurve::OFF_FILLET)) { + // calcolo seconda superifice offsettata del raggio utensile + sovramateriale + PtrOwner pSrfOff2 ( pSrf->Clone()) ; + if ( IsNull( pSrfOff2)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + if ( ! pSrfOff2->Offset( - dOffs , ICurve::OFF_FILLET) || ! pSrfOff2->IsValid()) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } - // ciclo sulle curve risultanti - while ( OffsCrv2.GetCurveCount() > 0) { + // ciclo sulle superfici risultanti + bStart = true ; + nChunks = pSrfOff2->GetChunkCount() ; + for ( int nC = 0 ; nC < nChunks ; nC++) { + int nLoops = pSrfOff2->GetLoopCount( nC) ; + for ( int nL = 0 ; nL < nLoops ; nL ++) { - // 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) ; + PtrOwner pOffs2( CreateCurveComposite()) ; + if ( IsNull( pOffs2) || ! pOffs2->AddCurve( pSrfOff2->GetLoop( nC, nL))) { + 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() ; + // se richiesto, la inverto + if ( m_Params.m_bInvert) + pOffs2->Invert() ; - // sposto l'inizio a metà del tratto più lungo - AdjustContourStart( pOffs2) ; + // 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 = dElev ; - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; - if ( bUnderStart) - dStElev = max( dStElev, dElev) ; - 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) + // 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 ; - } - 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 ; + // 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 = dElev ; + bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + if ( bUnderStart) + dStElev = max( dStElev, dElev) ; + 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, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn 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)) { + // altrimenti solo collegamento + else { + SetFeed( GetStartFeed()) ; + GetCurrPos( ptP1) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { 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") ; + } + // 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 ( nC != nChunks-1 || nL != nLoops-1) { + 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 ; + } + } } } } - } - } - } + } + } + } return true ; } //---------------------------------------------------------------------------- bool -Pocketing::CalcZigZag( const ICurveComposite* pOffs, - ICRVCOMPOPOVECTOR& vpCrvs) +Pocketing::CalcZigZag( const ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vpCrvs) { - // ingombro del contorno offsettato + // vettore di curve che delimitano la superficie + ICRVCOMPOPVECTOR vpCrvLoop ; + for ( int nL = 0 ; nL < pSrf->GetLoopCount( 0) ; nL ++) { + vpCrvLoop.push_back( CreateCurveComposite()) ; + if ( ! vpCrvLoop.back()->AddCurve( pSrf->GetLoop( 0, nL))) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + } + + // ingombro del contorno offsettato BBox3d b3Pocket ; - pOffs->GetLocalBBox( b3Pocket) ; + pSrf->GetLocalBBox( b3Pocket) ; Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - // lunghezza del contorno offsettato - double dLen ; pOffs->GetLength( dLen) ; + // lunghezza dei contorni offsettati + DBLVECTOR vLen( vpCrvLoop.size()) ; + for ( size_t i = 0 ; i < vLen.size() ; i++) + vpCrvLoop[i]->GetLength( vLen[i]) ; - // passi in Y + // passi in Y int nYStep = static_cast( ceil( ( dDimY - 20 * EPS_SMALL) / GetSideStep())) ; double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ; - // tratto valido + // tratto valido struct Section { bool bActive ; Point3d ptS ; Point3d ptE ; double dOs ; double dOe ; + size_t nIdxS ; // indice posizione in vpCrvLoop della curva di offset a cui appartiene ptS + size_t nIdxE ; // indice posizione in vpCrvLoop della curva di offset a cui appartiene ptE } ; - // raccolta di tratti + // raccolta di tratti typedef vector> VECVECSECT ; VECVECSECT vvSec ; vvSec.resize( nYStep + 1) ; - // calcolo le linee di svuotatura + // calcolo le linee di svuotatura int nCount = 0 ; for ( int i = 0 ; i <= nYStep ; ++ i) { - // determino senso + // determino senso bool bPlus = (( i % 2) == 0) ; - // definisco la linea + // 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)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; - } - // calcolo la classificazione della curva rispetto al contorno esterno offsettato - IntersCurveCurve intCC( *pLine, *pOffs) ; + } + + // calcolo la classificazione della curva rispetto alla regione offsettata CRVCVECTOR ccClass ; - if ( ! intCC.GetCurveClassification( 0, ccClass)) { + if ( ! pSrf->GetCurveClassification( *pLine, ccClass)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; - } - // determino gli intervalli di curva da conservare + } + // 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) + 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) + } + // 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 + while ( bFound) { + // determino i dati della sezione Section Sect ; - Sect.bActive = true ; + 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 + + // cerco la curva della regione di offset che passa per ptS + bool bCrvFound = false ; + for ( size_t k = 0 ; ! bCrvFound && k < vpCrvLoop.size() ; k++) { + bCrvFound = vpCrvLoop[k]->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ; + if ( bCrvFound) + Sect.nIdxS = k ; + } + if ( ! bCrvFound) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + + // cerco la curva della regione di offset che passa per ptE + bCrvFound = false ; + for ( size_t k = 0 ; ! bCrvFound && k < vpCrvLoop.size() ; k++) { + bCrvFound = vpCrvLoop[k]->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ; + if ( bCrvFound) + Sect.nIdxE = k ; + } + if ( ! bCrvFound) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + + // inserisco nel contenitore vvSec[i].emplace_back( Sect) ; ++ nCount ; - // recupero successivo intervallo + // recupero successivo intervallo bFound = ( bPlus ? inOk.GetNext( dParS, dParE) : inOk.GetPrev( dParE, dParS)) ; } } - // dominio del contorno - double dUmin, dUmax ; - pOffs->GetDomain( dUmin, dUmax) ; - double dUspan = dUmax - dUmin ; + // dominio del contorno + DBLVECTOR vUmax( vpCrvLoop.size()) ; + DBLVECTOR vUmin( vpCrvLoop.size()) ; + DBLVECTOR vUspan( vpCrvLoop.size()) ; + for ( size_t i = 0 ; i < vpCrvLoop.size() ; i++) { + vpCrvLoop[i]->GetDomain( vUmin[i], vUmax[i]) ; + vUspan[i] = vUmax[i] - vUmin[i] ; + } - // creo i percorsi di svuotatura + // creo i percorsi di svuotatura vpCrvs.reserve( nCount) ; int nI = -1, nJ = -1 ; while ( true) { - // se sezione non valida + // se sezione non valida if ( nI < 0 || nJ < 0) { - // ricerco la prima valida + // 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) { @@ -2344,24 +2855,24 @@ Pocketing::CalcZigZag( const ICurveComposite* pOffs, } } } - // se trovata, creo nuova curva composita + // se trovata, creo nuova curva composita if ( nI >= 0 && nJ >= 0) { - // creo la curva + // creo la curva vpCrvs.emplace_back( CreateCurveComposite()) ; - // aggiungo punto iniziale + // aggiungo punto iniziale vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ; } - // altrimenti, esco + // altrimenti, esco else break ; } - // determino senso + // determino senso bool bPlus = (( nI % 2) == 0) ; - // 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) ; - // cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno + // cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno double dUstart = Sec.dOe ; double dUref = ( bPlus ? INFINITO : - INFINITO) ; int nNextI = -1 ; @@ -2371,10 +2882,13 @@ Pocketing::CalcZigZag( const ICurveComposite* pOffs, for ( int l = li ; l < int( vvSec[k].size()) ; ++ l) { if ( ! vvSec[k][l].bActive) continue ; + // la nuova sezione deve partire dalla stessa curva su cui ci si è fermati + if ( vvSec[k][l].nIdxS != Sec.nIdxE) + continue ; double dU = vvSec[k][l].dOs ; if ( bPlus) { if ( dU < dUstart) - dU += dUspan ; + dU += vUspan[Sec.nIdxE] ; if ( dU < dUref) { dUref = dU ; nNextI = k ; @@ -2383,7 +2897,7 @@ Pocketing::CalcZigZag( const ICurveComposite* pOffs, } else { if ( dU > dUstart) - dU -= dUspan ; + dU -= vUspan[Sec.nIdxE] ; if ( dU > dUref) { dUref = dU ; nNextI = k ; @@ -2393,31 +2907,32 @@ Pocketing::CalcZigZag( const ICurveComposite* pOffs, } li = 0 ; } - // se trovato, aggiungo il tratto di contorno e continuo + // se trovato, aggiungo il tratto di contorno e continuo if ( nNextI != -1) { PtrOwner pCopy ; + size_t idx = vvSec[nNextI][nNextJ].nIdxS ; if ( bPlus) { - if ( dUref > dUmax) - dUref -= dUspan ; - pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; + if ( dUref > vUmax[idx]) + dUref -= vUspan[idx] ; + pCopy.Set( vpCrvLoop[idx]->CopyParamRange( dUstart, dUref)) ; if ( ! IsNull( pCopy)) { double dCLen ; pCopy->GetLength( dCLen) ; - if ( dCLen > 0.5 * dLen) { - pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; + if ( dCLen > 0.5 * vLen[idx]) { + pCopy.Set( vpCrvLoop[idx]->CopyParamRange( dUref, dUstart)) ; if ( ! IsNull( pCopy)) pCopy->Invert() ; } } } else { - if ( dUref < dUmin) - dUref += dUspan ; - pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; + if ( dUref < vUmin[idx]) + dUref += vUspan[idx] ; + pCopy.Set( vpCrvLoop[idx]->CopyParamRange( dUref, dUstart)) ; if ( ! IsNull( pCopy)) { pCopy->Invert() ; double dCLen ; pCopy->GetLength( dCLen) ; - if ( dCLen > 0.5 * dLen) - pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; + if ( dCLen > 0.5 * vLen[idx]) + pCopy.Set( vpCrvLoop[idx]->CopyParamRange( dUstart, dUref)) ; } } BBox3d b3Copy ; @@ -2441,266 +2956,274 @@ Pocketing::CalcZigZag( const ICurveComposite* pOffs, return true ; } + //---------------------------------------------------------------------------- bool -Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) -{ - // recupero distanze di sicurezza +Pocketing::AddOneWay( const ISurfFlatRegion* pSrf, 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 + // 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) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } - // determino numero e affondamento degli step + // determino numero e affondamento degli step int nStep = 1 ; nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; double dStep = dElev / nStep ; - // calcolo curva offsettata del raggio utensile + sovramateriale + // calcolo regione offsettata del raggio utensile + sovramateriale double dTRad = 0.5 * m_TParams.m_dDiam ; double dOffs = dTRad + GetOffsR() ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCompo, - dOffs, ICurve::OFF_FILLET)) { + PtrOwner pSrfOff1( pSrf->Clone()) ; + if( IsNull( pSrfOff1)) + return false ; + if ( ! pSrfOff1->Offset( - dOffs, ICurve::OFF_FILLET) || ! pSrfOff1->IsValid()) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; - } + } - // ciclo sulle curve risultanti - while ( OffsCrv.GetCurveCount() > 0) { + // ciclo sulle superifici risultanti + for ( int nC = 0 ; nC < pSrfOff1->GetChunkCount() ; nC ++) { + // ciclo sulle curve + for ( int nL = 0 ; nL < pSrfOff1->GetLoopCount( nC) ; nL ++) { - // 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 ; - } + // recupero la curva di offset + PtrOwner pOffs( CreateCurveComposite()) ; + if ( IsNull( pOffs) || ! pOffs->AddCurve( pSrfOff1->GetLoop( nC, nL))) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + VerifyArcs( pOffs) ; + // se richiesto, la inverto + if ( m_Params.m_bInvert) + pOffs->Invert() ; - // se richiesto, la inverto - if ( m_Params.m_bInvert) - pOffs->Invert() ; + // sposto l'inizio a metà del tratto più lungo + AdjustContourStart( pOffs) ; - // sposto l'inizio a metà del tratto più lungo - AdjustContourStart( pOffs) ; + // coefficiente di riduzione feed di lavorazione di questa curva + double dFeedRid = min( GetSideStep() / m_TParams.m_dDiam, 1.0) ; - // 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 = dElev ; - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; - if ( bUnderStart) - dStElev = max( dStElev, dElev) ; - 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 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 = dElev ; + bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + if ( bUnderStart) + dStElev = max( dStElev, dElev) ; + 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, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; + return false ; + } } - // 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, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs)) { + m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link 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") ; + // 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 ; - } } - } - // 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 ; - } - 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") ; + 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 ; + } } } } } - } + } } - // calcolo seconda curva di offset - OffsetCurve OffsCrv2 ; + // calcolo seconda superficie di offset + PtrOwner pSrfOff2( pSrf->Clone()) ; + if( IsNull( pSrfOff2)) + return false ; double dExtra = min( 0.1 * m_TParams.m_dDiam, 1.0) ; - if ( ! OffsCrv2.Make( pCompo, - ( dOffs + dExtra), ICurve::OFF_FILLET)) { + if ( ! pSrfOff2->Offset( - ( dOffs + dExtra), ICurve::OFF_FILLET) || ! pSrfOff2->IsValid()) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; - } + } - // ciclo sulle curve risultanti - while ( OffsCrv2.GetCurveCount() > 0) { + // ciclo sulle superfici risultanti + int nC = 0 ; + int nChunks = pSrfOff2->GetChunkCount() ; - PtrOwner pOffs2( CreateCurveComposite()) ; - if ( IsNull( pOffs2) || ! pOffs2->AddCurve( OffsCrv2.GetLongerCurve())) { - m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + while ( nC < nChunks) { + PtrOwner pSrfChunk( pSrfOff2->CloneChunk( nC)) ; + if ( IsNull( pSrfChunk)) return false ; - } - // determino il riferimento di base e il box della svuotatura + // determino il riferimento di base e il box della svuotatura Frame3d frPocket ; - Point3d ptCen ; pCompo->GetCentroid( ptCen) ; + Point3d ptCen ; pSrfChunk->GetChunkCentroid( 0, ptCen) ; frPocket.Set( ptCen, vtExtr) ; frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pOffs2->ToLoc( frPocket) ; + pSrfChunk->ToLoc( frPocket) ; + BBox3d b3Pocket ; - pOffs2->GetLocalBBox( b3Pocket) ; + pSrfChunk->GetLocalBBox( b3Pocket) ; Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - // passi in Y + // passi in Y int nYStep = static_cast( ceil( ( dDimY + 2 * dExtra) / GetSideStep())) ; double dYStep = ( nYStep > 0 ? ( dDimY + 2 * dExtra) / nYStep : 0) ; -- nYStep ; - // calcolo le linee di svuotatura + // 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 + // 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)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // calcolo la classificazione della curva rispetto al contorno esterno offsettato - IntersCurveCurve intCC( *pLine, *pOffs2) ; + // calcolo la classificazione della curva rispetto alla superficie offsettata CRVCVECTOR ccClass ; - if ( ! intCC.GetCurveClassification( 0, ccClass)) { + if ( ! pSrfChunk->GetCurveClassification( *pLine, ccClass)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // determino gli intervalli di curva da conservare + // 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 + // inserisco i tratti validi double dParS, dParE ; bool bFound = inOk.GetFirst( dParS, dParE) ; while ( bFound) { - // calcolo inizio con affondamento + // 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 + // determino inizio attacco Point3d ptP ; if ( ! CalcLeadInStart( ptS, frPocket.VersX(), vtExtr, nullptr, ptP)) return false ; - // determino elevazione su inizio attacco + // determino elevazione su inizio attacco double dStElev ; if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; if ( bUnderStart) dStElev = max( dStElev, dElev) ; dStElev -= ( ptP - ptS) * vtExtr ; - // sempre approccio di collegamento + // 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 + // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pCompo, nullptr, ! m_Params.m_bInvert, bSplitArcs, true)) { + if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pSrf, nullptr, ! m_Params.m_bInvert, bSplitArcs, true)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } - // calcolo fine con affondamento + // 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 + // movimento al punto finale SetFeed( GetFeed()) ; if ( AddLinearMove( ptE) == GDB_ID_NULL) return false ; - // risalita + // risalita Point3d ptQ ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; @@ -2708,16 +3231,16 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - // recupero successivo intervallo + // 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) { + // se ultimo movimento di ultima area, aggiungo retrazione globale + if ( j == nStep && i == nYStep && ! bFound && nC == nChunks - 1 ) { 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 + // altrimenti aggiungo retrazione di collegamento else { if ( ! AddLinkRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; @@ -2727,6 +3250,7 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con } } } + nC ++ ; } return true ; @@ -2734,128 +3258,131 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con //---------------------------------------------------------------------------- bool -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) +Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, bool bMidOpen, + const Point3d& ptMidOpen, const Vector3d& vtMidOut) { - // recupero distanze di sicurezza + // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; - // lunghezza di approccio/retrazione + // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // ciclo sulle regioni + // 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 + // 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 ; } - if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv)) - return false ; - // se terminate le regioni, esco + + if ( ! CalcSpiral( pSrf, nReg, bSplitArcs, pMCrv, pRCrv)) + return false ; + + // se terminate le regioni, esco if ( pMCrv->GetCurveCount() == 0) break ; ++ nReg ; - // se prima regione e gestione lato aperto + // se prima regione e gestione lato aperto bool bOutStart = ( nReg == 1 && bMidOpen) ; if ( bOutStart) { - // calcolo il punto fuori + // calcolo il punto fuori Point3d ptOut = ptMidOpen + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; - // aggiungo al ritorno l'uscita + // aggiungo al ritorno l'uscita if ( pRCrv->GetCurveCount() == 0) { Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ; pRCrv->AddPoint( ptStart) ; } pRCrv->AddLine( ptOut, true) ; - // premetto alla spirale la partenza da fuori + // premetto alla spirale la partenza da fuori pMCrv->AddLine( ptOut, false) ; } - // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } - - // determino numero e affondamento degli step + + // 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 + + // ciclo sugli step Point3d ptP1 ; for ( int j = 1 ; j <= nStep ; ++ j) { - // ciclo sulle curve elementari + // ciclo sulle curve elementari for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; - // aggiungo affondamento + // aggiungo affondamento pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // se prima entità + // se prima entità if ( i == 0 ) { - // dati inizio entità + // dati inizio entità Point3d ptStart ; pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo + // se primo step, approccio e affondo if ( j == 1) { - // determino inizio attacco + // determino inizio attacco if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) return false ; - // determino elevazione su inizio attacco + // determino elevazione su inizio attacco double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; if ( bUnderStart) dStElev = max( dStElev, dElev) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + + // 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) { + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { ptP1 += vtExtr * dStElev ; dStElev = 0 ; } - // approccio al punto iniziale + // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart)) { m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ; return false ; } - // aggiungo attacco + // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } } - // altrimenti solo collegamento + // altrimenti solo collegamento else { SetFeed( GetStartFeed()) ; GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, pRCrv, ! m_Params.m_bInvert, bSplitArcs, bOutStart)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; } } } - // elaborazioni sulla curva corrente + // elaborazioni sulla curva corrente if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; Point3d ptP3 = pLine->GetEnd() ; @@ -2874,19 +3401,19 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; } - // se ultima entità + // se ultima entità if ( i == nMaxInd) { - // se step intermedio, ritorno all'inizio direttamente + // se step intermedio, ritorno all'inizio direttamente if ( j < nStep) { - // se necessario ritorno all'inizio + // se necessario ritorno all'inizio if ( nMaxRInd >= 0) { - // copio la curva di ritorno + // copio la curva di ritorno PtrOwner pRet( pRCrv->Clone()) ; if ( IsNull( pRet)) return false ; - // aggiungo affondamento + // aggiungo affondamento pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco + // 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) @@ -2894,20 +3421,20 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c else pRet->Clear() ; } - // emetto + // emetto SetFeed( GetFeed()) ; if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) return false ; } } - // atrimenti ultimo step, uscita e retrazione + // atrimenti ultimo step, uscita e retrazione else { - // dati fine entità + // dati fine entità Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita + // aggiungo uscita Point3d ptP1 ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; @@ -2930,117 +3457,114 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c //---------------------------------------------------------------------------- bool -Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) +Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) { - // recupero distanze di sicurezza + // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; - // lunghezza di approccio/retrazione + // 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) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } - - // ciclo sulle regioni + // ciclo sulle regioni const int MAX_REGS = 50 ; int nReg = 0 ; while ( nReg < MAX_REGS) { - - // calcolo la spirale dall'interno all'esterno + // 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 ; } - if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv)) - return false ; - // se terminate le regioni, esco + if ( ! CalcSpiral( pSrf, nReg, bSplitArcs, pMCrv, pRCrv)) + return false ; + // se terminate le regioni, esco if ( pMCrv->GetCurveCount() == 0) break ; ++ nReg ; - // inverto i percorsi, perchè sono calcolati dall'esterno all'interno + // inverto i percorsi, perchè sono calcolati dall'esterno all'interno pMCrv->Invert() ; pRCrv->Invert() ; - - // determino numero e affondamento degli step + + // 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 + + // ciclo sugli step Point3d ptP1 ; for ( int j = 1 ; j <= nStep ; ++ j) { - // ciclo sulle curve elementari + // ciclo sulle curve elementari for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente + // curva corrente const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva + // copio la curva PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; - // aggiungo affondamento + // aggiungo affondamento pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // se prima entità + // se prima entità if ( i == 0 ) { - // dati inizio entità + // dati inizio entità Point3d ptStart ; pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // se primo step, approccio e affondo + // se primo step, approccio e affondo if ( j == 1) { - // determino inizio attacco + // 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 + // determino elevazione su inizio attacco double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dStElev) ; if ( bUnderStart) dStElev = max( dStElev, dElev) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + // 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) { + GetLeadInType() == POCKET_LI_HELIX || + GetLeadInType() == POCKET_LI_GLIDE) { ptP1 += vtExtr * dStElev ; dStElev = 0 ; } - // approccio al punto iniziale + // 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 + // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, pRCrv, m_Params.m_bInvert, bSplitArcs)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } + } - // altrimenti solo collegamento + // altrimenti solo collegamento else { SetFeed( GetStartFeed()) ; GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrf, pRCrv, m_Params.m_bInvert, bSplitArcs)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; } } } - // elaborazioni sulla curva corrente + // elaborazioni sulla curva corrente if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; Point3d ptP3 = pLine->GetEnd() ; @@ -3058,20 +3582,20 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, SetFeed( GetFeed()) ; if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) return false ; - } - // se ultima entità + } + // se ultima entità if ( i == nMaxInd) { - // se step intermedio + // se step intermedio if ( j < nStep) { - // se necessario ritorno all'inizio + // se necessario ritorno all'inizio if ( nMaxRInd >= 0) { - // copio la curva di ritorno + // copio la curva di ritorno PtrOwner pRet( pRCrv->Clone()) ; if ( IsNull( pRet)) return false ; - // aggiungo affondamento + // aggiungo affondamento pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; - // se attacco a scivolo, accorcio della lunghezza dell'attacco + // 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) @@ -3079,20 +3603,20 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, else pRet->Clear() ; } - // emetto + // emetto SetFeed( GetFeed()) ; if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL) return false ; } } - // atrimenti ultimo step, uscita e retrazione + // atrimenti ultimo step, uscita e retrazione else { - // dati fine entità + // dati fine entità Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; - // aggiungo uscita + // aggiungo uscita Point3d ptQ ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; @@ -3110,117 +3634,183 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, } } } + + return true ; } + //---------------------------------------------------------------------------- bool -Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) -{ - // inizializzo i risultati +Pocketing::CalcSpiral( const ISurfFlatRegion * pSrf , int nReg, bool bSplitArcs, + ICurveComposite* pMCrv, ICurveComposite* pRCrv) +{ + // inizializzo i risultati pMCrv->Clear() ; pRCrv->Clear() ; - // primo offset pari al raggio utensile + sovramateriale + // primo offset pari al raggio utensile + sovramateriale double dTRad = 0.5 * m_TParams.m_dDiam ; - double dOffs = dTRad + GetOffsR() ; + double dOffs = dTRad + GetOffsR() ; - // 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 ; - } - - // ciclo di offset verso l'interno + // ciclo di offset verso l'interno const int MAX_ITER = 1000 ; int nIter = 0 ; - ICURVEPOVECTOR vOffs ; - ICURVEPOVECTOR vCrvStack ; - DBLVECTOR vRadStack ; - PtrOwner pOffs ; - double dCurrRad = GetCurveRadius( pCompo) ; + + PtrOwner pSrfOff( pSrf->Clone()) ; // superficie che viene offsettata + PtrOwner pSrfOffOld( pSrf->Clone()) ; // superficie di offset all'iterazione precedente + PtrOwner pSrfOff1 ; // superficie di offset alla prima iterazione + if ( IsNull( pSrfOff) || IsNull( pSrfOffOld)) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + ISURFFRPOVECTOR vSrfStack ; + ICRVCOMPOPVECTOR vOffs ; + PtrOwner pOffs ; + size_t LastExtLoopPos = 0 ; + while ( nIter < MAX_ITER) { - // calcolo - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( ( nIter == 0 ? (ICurve*) pCompo : pOffs), - dOffs, ICurve::OFF_FILLET) || - ( nIter == 0 && nReg == 0 && OffsCrv.GetCurveCount() == 0)) { + + // calcolo offset + if ( ! pSrfOff->Offset( - dOffs, ICurve::OFF_FILLET)) { + pSrfOff->Clear() ; m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + // return false ; + } + // salvo la prima surface di offset per CalcBoundedLink + if ( nIter == 0 && pSrfOff->IsValid()) + pSrfOff1.Set( pSrfOff->Clone()) ; + if ( IsNull( pSrfOff1) || ! pSrfOff1->IsValid()) return false ; - } - // se primo offset e richiesta regione oltre il massimo, esco - if ( nIter == 0 && nReg >= OffsCrv.GetCurveCount()) + + // se primo offset e richiesta regione oltre il massimo, esco + int nChunks = pSrfOff->GetChunkCount() ; + if ( nIter == 0 && nReg >= nChunks) return true ; - // recupero le curve di offset e le metto sullo stack (se primo offset solo quella voluta) + // recupero le superfici 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) ; + while ( nCount < nChunks) { + if ( nIter != 0 || nReg == nCount) { + vSrfStack.emplace_back( pSrfOff->CloneChunk( nCount)) ; if ( nIter == 0) - break ; + break ; } - else - delete( pCrv) ; - pCrv = OffsCrv.GetCurve() ; - ++ nCount ; + 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() ; + + // recupero la prossima superficie di offset + if ( ! vSrfStack.empty() && ( pSrfOff->IsValid() || dOffs < dTRad + EPS_ZERO)) { + pSrfOff.Set( Release( vSrfStack.back())) ; + vSrfStack.pop_back() ; } - double dRad = GetCurveRadius( pNextOffs) ; - bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ; + + bool bNextOk = pSrfOff->IsValid() ; bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ; - // 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) { - // nuovo valore pari al raggio + // se offset va bene aggiorno pSrfOffOld + if ( pSrfOff->IsValid()) + pSrfOffOld.Set( pSrfOff->Clone()) ; + // se non valido ma riducibile, provo con offset ridotto al raggio utensile + else if ( ! bSmallRad) { + pSrfOff.Set( pSrfOffOld->Clone()) ; + // nuovo valore pari al raggio dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ; + continue ; } - // altrimenti esco - else + // altrimenti esco + else break ; - // incremento contatore iterazioni + + // verifico se circonferenza o circonferenze concentriche + if ( CircleSpiral( pSrfOff, bSplitArcs, vOffs, pRCrv)) + break ; + + // Inserisco le curve che delimitano la superficie di offset nel vettore vOffs in modo che siano ordinate dalla + // più esterna alla più interna + for ( int nL = 0 ; nL < pSrfOff->GetLoopCount( 0) ; nL ++) { + + pOffs.Set( GetCurveComposite( pSrfOff->GetLoop( 0, nL))) ; + if ( IsNull( pOffs)) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + + // Se sono al primo offset inserisco le curve senza preoccuparmi dell'ordine + if ( nIter == 0) { + vOffs.emplace_back( Release( pOffs)) ; + LastExtLoopPos = vOffs.size() ; + } + // altrimenti cerco il punto dove aggiungere la curva + else { + // creo la sua superficie racchiusa dalla curva da inserire + PtrOwner pSrfTmp( CreateSurfFlatRegion()) ; + if ( IsNull( pSrfTmp) || ! pSrfTmp->AddExtLoop( pOffs->Clone())) + vOffs.push_back( Release( pOffs)) ; + else { + // scorro vOffs fino a quando trovo una curva inclusa nella regione definita da pOffs + auto it = vOffs.begin() ; + while ( it != vOffs.end()) { + CRVCVECTOR ccClass ; + // se non riesco a classificare passo alla curva successiva + if ( ! pSrfTmp->GetCurveClassification( **it, ccClass)) + continue ; + if ( ccClass.size() != 1) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + if ( ccClass[0].nClass == CRVC_IN) + break ; + it ++ ; + } + + // Inserisco pOffs in vOffs + if ( it != vOffs.end()) { + // se loop esterno per quell'offset aggiorno il valore di LastExtCrvPos + if ( nL == 0) + LastExtLoopPos = it - vOffs.begin() ; + vOffs.insert( it, Release( pOffs)) ; + } + // se non ho trovato in vOffs una curva inclusa nella regione generata da pOffs, inserisco pOffs subito dopo + // il loop esterno dell'offset precedente (che si trova in LastExtCrvPos) + else { + vOffs.insert( vOffs.begin() + LastExtLoopPos + 1, Release( pOffs)) ; + // se loop esterno per quell'offset aggiorno il valore di LastExtCrvPos + if ( nL == 0) + LastExtLoopPos = LastExtLoopPos + 1 ; + + } + } + } + } + // nuovo valore pari allo step + dOffs = GetSideStep() ; + + // incremento contatore iterazioni ++ nIter ; } - // calcolo i collegamenti + // start points per le curve + Point3d ptOld ; + AdjustContourStart( vOffs[0]) ; + vOffs[0]->GetEndPoint( ptOld) ; + // per le curve successive scelgo come start point quello più vicino all'end point della curva precedente + for ( size_t i = 1 ; i < vOffs.size() ; i++) { + double dParam ; int nFlag ; + if ( DistPointCurve( ptOld, *vOffs[i]).GetParamAtMinDistPoint( 0, dParam, nFlag)) + vOffs[i]->ChangeStartPoint( dParam) ; + vOffs[i]->GetEndPoint( ptOld) ; + } + + // calcolo i collegamenti ICURVEPOVECTOR vLinks( vOffs.size()) ; for ( int i = 1 ; i < int( vOffs.size()) ; ++ i) { - // punti di inizio e fine + // 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) + // calcolo il collegamento (garantendo che non esca dalla svuotatura) PtrOwner pCrvLink( CreateCurveComposite()) ; - if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) + if ( CalcBoundedLink( ptStart, ptEnd, pSrfOff1, pCrvLink)) vLinks[i].Set( Release( pCrvLink)) ; else { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; @@ -3228,19 +3818,20 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, } } - // calcolo il percorso di ritorno + // calcolo il percorso di ritorno if ( vOffs.size() >= 2) { - // punti di inizio e fine + pRCrv->Clear() ; + // 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) + // calcolo il ritorno (garantendo che non esca dalla svuotatura) PtrOwner pCrvLink( CreateCurveComposite()) ; - if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) { + if ( CalcBoundedLink( ptStart, ptEnd, pSrfOff1, pCrvLink)) { pRCrv->AddCurve( Release( pCrvLink)) ; pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; - // se necessario, approssimo archi con rette + // se necessario, approssimo archi con rette if ( bSplitArcs && ! ApproxWithLines( pRCrv)) { m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Linear Approx not computable") ; return false ; @@ -3253,121 +3844,190 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, } } - // creo il percorso di lavoro a partire dalla raccolta degli offset e dei collegamenti + // 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 + // se collegamento da aggiungere if ( ! IsNull( vLinks[i])) { - // accodo nel percorso di lavorazione + // accodo nel percorso di lavorazione pMCrv->AddCurve( Release( vLinks[i])) ; } - // se richiesta percorrenza invertita + // se richiesta percorrenza invertita if ( m_Params.m_bInvert) vOffs[i]->Invert() ; - // aggiungo la curva - pMCrv->AddCurve( Release( vOffs[i])) ; - } + // aggiungo la curva + pMCrv->AddCurve( Release( (PtrOwner)vOffs[i])) ; - // verifico il percorso di lavoro + } + // verifico il percorso di lavoro if ( pMCrv->GetCurveCount() == 0) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // se necessario, approssimo archi con rette + // se necessario, approssimo archi con rette if ( bSplitArcs && ! ApproxWithLines( pMCrv)) { m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Linear Approx not computable") ; return false ; - } - // eventuale sistemazione archi + } + // eventuale sistemazione archi VerifyArcs( pMCrv) ; return true ; } + //---------------------------------------------------------------------------- bool -Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound, - ICurveComposite* pCrvLink) -{ - // recupero il vettore estrusione - Vector3d vtExtr ; - pCrvBound->GetExtrusion( vtExtr) ; - // determino il riferimento naturale della svuotatura (OCS con il vettore estrusione come asse Z) - Frame3d frLoc ; - frLoc.Set( ORIG, vtExtr) ; - // porto la curva di contenimento in locale a questo riferimento - CurveLocal CrvOutLoc( pCrvBound, GLOB_FRM, frLoc) ; - - // creo la retta che li unisce +Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ISurfFlatRegion* pSrf, + ICurveComposite* pCrvLink) +{ + // creo la retta PtrOwner pLine( CreateCurveLine()) ; - if ( IsNull( pLine) || ! pLine->Set( ptStart, ptEnd)) + 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) ; + } - // classifico la curva di collegamento rispetto a quella di contenimento + // classifico la curva di collegamento rispetto alla superficie di contenimento CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *LineLoc, *CrvOutLoc) ; - intCC.GetCurveClassification( 0, ccClass) ; - // se nessuno o un solo tratto e interno, la retta è il collegamento + pSrf->GetCurveClassification( *pLine, 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 ; } - // altrimenti combino i tratti interni di retta con tratti opportuni della curva di contenimento + // altrimenti combino i tratti interni di retta con tratti opportuni delle curve che delimitano la superficie di contenimento else { - PtrOwner pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo)) + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo)) return false ; - for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) { + + // curve che delimitano la superficie + ICURVEPOVECTOR vpCrvBound ; + for ( int nC = 0 ; nC < pSrf->GetChunkCount() ; nC ++) + for ( int nL = 0 ; nL < pSrf->GetLoopCount( nC) ; nL ++) + vpCrvBound.emplace_back( pSrf->GetLoop( nC, nL)) ; + + 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 ; - pLine->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; + + else if ( ccClass[j].nClass == CRVC_OUT) { + Point3d ptS ; + pLine->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ; double dOffS ; - pCrvBound->GetParamAtPoint( ptS, dOffS) ; - Point3d ptE ; + // cerco la curva dell'offset che passa per ptS + bool bFound = false ; + size_t CrvIdx ; + auto it = vpCrvBound.begin() ; + for ( size_t k = 0 ; ! bFound && k < vpCrvBound.size() ; k++) { + bFound = vpCrvBound[k]->GetParamAtPoint( ptS, dOffS) ; + if ( bFound) + CrvIdx = k ; + } + if ( ! bFound) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } + + Point3d ptE ; pLine->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; double dOffE ; - 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 ( dLenA < dLenB) { - pCompo->AddCurve( Release( pCrvA)) ; + // ptE deve trovarsi sulla stessa curva di ptS + bFound = vpCrvBound[CrvIdx]->GetParamAtPoint( ptE, dOffE) ; + // se non lo trovo sulla curva di ptS, cerco in ccClass un altro intervallo il cui ptE si trova sulla curva di ptS + if ( ! bFound) { + while ( ! bFound && j < int( ccClass.size())) { + j ++ ; + pLine->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ; + bFound = vpCrvBound[CrvIdx]->GetParamAtPoint( ptE, dOffE) ; + } + // se intervallo non esiste, è errore + if ( ! bFound) { + m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; + return false ; + } } - else { - pCrvB->Invert() ; - pCompo->AddCurve( Release( pCrvB)) ; - } - } - } + + // recupero i due possibili percorsi e uso il più corto + PtrOwner pCrvA( vpCrvBound[CrvIdx]->CopyParamRange( dOffS, dOffE)) ; + PtrOwner pCrvB( vpCrvBound[CrvIdx]->CopyParamRange( dOffE, dOffS)) ; + if ( IsNull( pCrvA) || IsNull( pCrvB)) + return false ; + double dLenA ; pCrvA->GetLength( dLenA) ; + double dLenB ; pCrvB->GetLength( dLenB) ; + if ( dLenA < dLenB) { + pCompo->AddCurve( Release( pCrvA)) ; + } + else { + pCrvB->Invert() ; + pCompo->AddCurve( Release( pCrvB)) ; + } + } + } pCrvLink->AddCurve( Release( pCompo)) ; return true ; } + +} + + +// ---------------------------------------------------------------------------- +bool +Pocketing::CircleSpiral( ISurfFlatRegion* pSrf, bool bSplitArcs, ICRVCOMPOPVECTOR& vOffs, ICurveComposite * pRCrv) +{ + int nLoops = pSrf->GetLoopCount( 0) ; + + // posso usare CalcCircleSpiral se al massimo ci sono due circonferenze concentriche + if ( nLoops > 2) + return false ; + + ICurveComposite * pExt = GetCurveComposite( pSrf->GetLoop( 0, 0)) ; + Point3d ptCen ; Vector3d vtN ; double dRad ; bool bCCW ; + // verifico sia circonferenza + if ( ! pExt->IsACircle( 10 * EPS_SMALL, ptCen, vtN, dRad, bCCW )) + return false ; + + vOffs.push_back( CreateCurveComposite()) ; + // se ho solo il loop esterno + if ( nLoops == 1) { + 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 ) ; + m_dMaxHelixRad = dIntRad ; + } + return CalcCircleSpiral( ptCen, vtN, dRad, dIntRad, bSplitArcs, vOffs[0], pRCrv) ; + } + + // se ho anche un loop interno, verifico sia una circonfernza concentrica al loop esterno + ICurveComposite * pInt = GetCurveComposite( pSrf->GetLoop( 0, 1)) ; + Point3d ptCen2 ; Vector3d vtN2 ; double dRad2 ; bool bCCW2 ; + if ( ! pInt->IsACircle( 100 * EPS_SMALL, ptCen2, vtN2, dRad2, bCCW2) || ! AreSamePointEpsilon( ptCen, ptCen2, EPS_SMALL)) + return false ; + + if ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT && GetLeadInType() == POCKET_LI_HELIX) { + m_dMaxHelixRad = min( 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam), dRad - dRad2) ; + } + + return CalcCircleSpiral( ptCen, vtN, dRad, dRad2, bSplitArcs, vOffs[0], pRCrv) ; + } //---------------------------------------------------------------------------- bool Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad, - bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) + bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) { - // raggio della circonferenza esterna + // raggio della circonferenza esterna if ( dOutRad < 10 * EPS_SMALL) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // imposto versore estrusione sulle curve composite + // imposto versore estrusione sulle curve composite pMCrv->SetExtrusion( vtN) ; pRCrv->SetExtrusion( vtN) ; - // creo e inserisco la circonferenza esterna + // creo e inserisco la circonferenza esterna PtrOwner pArc( CreateCurveArc()) ; if ( IsNull( pArc) || ! pArc->Set( ptCen, vtN, dOutRad)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; @@ -3375,14 +4035,14 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d } Vector3d vtDir = pArc->GetStartVersor() ; pMCrv->AddCurve( Release( pArc)) ; - // se richiesta percorrenza invertita + // se richiesta percorrenza invertita if ( m_Params.m_bInvert) pMCrv->Invert() ; - // se raggio esterno maggiore dell'interno + // se raggio esterno maggiore dell'interno if ( dOutRad > dIntRad + 10 * EPS_SMALL) { - // aggiungo le semicirconferenze della spirale ( devono essere in numero dispari) + // aggiungo le semicirconferenze della spirale ( devono essere in numero dispari) int nStep = int( ceil( ( dOutRad - dIntRad) / ( 0.5 * GetSideStep()))) ; if ( IsEven( nStep)) nStep += 1 ; @@ -3394,25 +4054,25 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d pMCrv->AddArcTg( ptCen + vtDir * ( dOutRad - i * dStep)) ; } - // aggiungo la circonferenza interna + // aggiungo la circonferenza interna pMCrv->AddArcTg( ptCen + vtDir * dIntRad) ; pMCrv->AddArcTg( ptCen - vtDir * dIntRad) ; } - // verifico il percorso di lavoro + // verifico il percorso di lavoro if ( pMCrv->GetCurveCount() == 0) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } - // se necessario, approssimo con rette + // se necessario, approssimo con rette if ( bSplitArcs && ! ApproxWithLines( pMCrv)) { m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Linear Approx not computable") ; return false ; } - // eventuale sistemazione archi + // eventuale sistemazione archi VerifyArcs( pMCrv) ; - // calcolo l'eventuale percorso di ritorno + // calcolo l'eventuale percorso di ritorno Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ; Point3d ptEnd ; pMCrv->GetEndPoint( ptEnd) ; Vector3d vtStart ; pMCrv->GetStartDir( vtStart) ; @@ -3423,7 +4083,7 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d return false ; } pRCrv->AddCurve( Release( pArc2)) ; - // inverto e eventualmente sistemo archi + // inverto e eventualmente sistemo archi pRCrv->Invert() ; VerifyArcs( pRCrv) ; } @@ -3434,18 +4094,18 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d //---------------------------------------------------------------------------- bool Pocketing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr, bool bOutStart) + double dElev, double dAppr, bool bOutStart) { SetFlag( 1) ; - // se con aggregato da sotto + // se con aggregato da sotto if ( m_bAggrBottom) { - // aggiuntivo in Z + // aggiuntivo in Z double dAggZ = max( dElev + max( dSafeAggrBottZ, dAppr), 0.) ; - // distanza dal bordo del pezzo + // distanza dal bordo del pezzo double dDistBottom ; if ( ! GetDistanceFromRawSide( m_nPhase, ptP, m_vtAggrBottom, dDistBottom)) dDistBottom = 0 ; - // pre-approccio + // pre-approccio Point3d ptP0 = ptP - Z_AX * dAggZ + m_vtAggrBottom * ( dDistBottom + m_AggrBottom.dEncH + dSafeZ) ; Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAggZ - dElev) ; // se rinvio da sotto che richiede speciale rotazione @@ -3468,42 +4128,42 @@ 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 ( dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { - // se distanza di sicurezza minore di distanza di inizio + // se distanza di sicurezza minore di distanza di inizio if ( dSafeDist < dAppr + 10 * EPS_SMALL) { - // 1 -> punto sopra inizio + // 1 -> punto sopra inizio Point3d ptP1 = ptP + vtTool * ( dElev + dAppr) ; if ( ( ! m_bAggrBottom && AddRapidStart( ptP1) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP1) == GDB_ID_NULL)) + ( m_bAggrBottom && AddRapidMove( ptP1) == GDB_ID_NULL)) return false ; } else { - // 1a -> punto sopra inizio + // 1a -> punto sopra inizio Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ; Point3d ptP1a = ptP1b + vtTool * ( dSafeDist - dAppr) ; if ( ( ! m_bAggrBottom && AddRapidStart( ptP1a) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP1a) == GDB_ID_NULL)) + ( m_bAggrBottom && AddRapidMove( ptP1a) == GDB_ID_NULL)) return false ; - // 1b -> punto appena sopra inizio + // 1b -> punto appena sopra inizio if ( ( dElev + dAppr) > EPS_SMALL) { SetFlag( 0) ; if ( AddRapidMove( ptP1b) == GDB_ID_NULL) return false ; } } - // affondo al punto iniziale + // affondo al punto iniziale SetFlag( 0) ; SetFeed( bOutStart ? GetStartFeed() : GetTipFeed()) ; if ( AddLinearMove( ptP) == GDB_ID_NULL) return false ; } else { - // affondo diretto al punto iniziale + // affondo diretto al punto iniziale SetFlag( 0) ; if ( ( ! m_bAggrBottom && AddRapidStart( ptP) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP) == GDB_ID_NULL)) + ( m_bAggrBottom && AddRapidMove( ptP) == GDB_ID_NULL)) return false ; } return true ; @@ -3512,25 +4172,25 @@ Pocketing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafe //---------------------------------------------------------------------------- bool Pocketing::AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) + double dElev, double dAppr) { - // 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 + // 1b -> punto appena sopra inizio Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ; if ( ( dElev + dAppr) > EPS_SMALL) { SetFlag( 0) ; if ( AddRapidMove( ptP1b) == GDB_ID_NULL) return false ; } - // affondo al punto iniziale + // affondo al punto iniziale SetFlag( 0) ; SetFeed( GetTipFeed()) ; if ( AddLinearMove( ptP) == GDB_ID_NULL) return false ; } else { - // affondo diretto al punto iniziale + // affondo diretto al punto iniziale SetFlag( 0) ; if ( AddRapidMove( ptP) == GDB_ID_NULL) return false ; @@ -3541,11 +4201,11 @@ Pocketing::AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double d //---------------------------------------------------------------------------- bool Pocketing::AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) + 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 + // 4 -> movimento di risalita sopra il punto finale SetFeed( GetEndFeed()) ; Point3d ptP4 = ptP + vtTool * ( dElev + dAppr) ; if ( AddLinearMove( ptP4) == GDB_ID_NULL) @@ -3557,41 +4217,41 @@ Pocketing::AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dS //---------------------------------------------------------------------------- bool Pocketing::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) + double dElev, double dAppr) { - // 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 ( dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { if ( dSafeDist < dAppr + 10 * EPS_SMALL) { - // 4 -> movimento di risalita sopra il punto finale + // 4 -> movimento di risalita sopra il punto finale SetFeed( GetEndFeed()) ; Point3d ptP4 = ptP + vtTool * ( dElev + dAppr) ; if ( AddLinearMove( ptP4) == GDB_ID_NULL) return false ; } else { - // 4a -> movimento di risalita appena sopra il punto finale + // 4a -> movimento di risalita appena sopra il punto finale Point3d ptP4a = ptP + vtTool * ( dElev + dAppr) ; if ( dElev + dAppr > EPS_SMALL) { SetFeed( GetEndFeed()) ; if ( AddLinearMove( ptP4a) == GDB_ID_NULL) return false ; } - // 4b -> movimento di risalita sopra il punto finale + // 4b -> movimento di risalita sopra il punto finale Point3d ptP4b = ptP4a + vtTool * ( dSafeDist - dAppr) ; if ( AddRapidMove( ptP4b) == GDB_ID_NULL) return false ; } } - // se con aggregato da sotto + // se con aggregato da sotto if ( m_bAggrBottom) { - // aggiuntivo in Z + // aggiuntivo in Z double dAggZ = max( dElev + max( dSafeAggrBottZ, dAppr), 0.) ; - // distanza dal bordo del pezzo + // distanza dal bordo del pezzo double dDistBottom ; if ( ! GetDistanceFromRawSide( m_nPhase, ptP, m_vtAggrBottom, dDistBottom)) dDistBottom = 0 ; - // post-retract + // post-retract Point3d ptP0 = ptP - Z_AX * dAggZ + m_vtAggrBottom * ( dDistBottom + m_AggrBottom.dEncH + dSafeZ) ; Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAggZ - dElev) ; if ( AddRapidMove( ptP0, MCH_CL_AGB_OUT) == GDB_ID_NULL) @@ -3611,15 +4271,15 @@ Pocketing::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ //---------------------------------------------------------------------------- bool Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, - const ICurveComposite* pRCrv, Point3d& ptP1) const + const ICurveComposite* pRCrv, Point3d& ptP1) const { - // Assegno tipo e parametri + // Assegno tipo e parametri int nType = GetLeadInType() ; if ( nType == POCKET_LI_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0)) nType = POCKET_LI_NONE ; - // senso di rotazione da dir tg a dir esterna + // senso di rotazione da dir tg a dir esterna bool bCcwRot = true ; - // Calcolo punto iniziale + // Calcolo punto iniziale switch ( nType) { case POCKET_LI_NONE : case POCKET_LI_ZIGZAG : @@ -3627,16 +4287,16 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con ptP1 = ptStart ; return true ; case POCKET_LI_GLIDE : - { - double dLen, 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 ; - } - ptP1 += vtN * ( vtN * ( ptStart - ptP1)) ; - return true ; + { + double dLen, 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 ; } + ptP1 += vtN * ( vtN * ( ptStart - ptP1)) ; + return true ; + } default : return false ; } @@ -3645,31 +4305,31 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con //---------------------------------------------------------------------------- bool Pocketing::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) -{ - // Assegno il tipo + const ISurfFlatRegion* pSrf, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced) +{ + // Assegno il tipo int nType = GetLeadInType() ; if ( bNoneForced || - AreSamePointEpsilon( ptP1, ptStart, 10 * EPS_SMALL) || - ( nType == POCKET_LI_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0))) + AreSamePointEpsilon( ptP1, ptStart, 10 * EPS_SMALL) || + ( nType == POCKET_LI_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0))) nType = POCKET_LI_NONE ; - // Se elica e fattibile lo creo + // Se elica e fattibile lo creo if ( nType == POCKET_LI_HELIX) { - // vettore dal punto al centro elica + // vettore dal punto al centro elica Vector3d vtCen = vtStart ; vtCen.Rotate( vtN, 0, ( bAtLeft ? 1 : - 1)) ; - // dati dell'elica + // dati dell'elica double dRad = min( 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam), m_dMaxHelixRad) ; Point3d ptCen = ptP1 + vtCen * dRad ; double dDeltaN = ( ptStart - ptP1) * vtN ; - double dAngCen = ceil( - dDeltaN / ( m_Params.m_dLiElev + 10 * EPS_SMALL)) * ( bAtLeft ? ANG_FULL : - ANG_FULL) ; - // verifico se fattibile - if ( VerifyLeadInHelix( pCompo, ptCen, dRad)) { - // creo l'elica - PtrOwner pArc( CreateCurveArc()) ; + double dAngCen = ceil( - dDeltaN / ( m_Params.m_dLiElev + 10 * EPS_SMALL)) * ( bAtLeft ? ANG_FULL : - ANG_FULL) ; + // verifico se fattibile + if ( VerifyLeadInHelix( pSrf, ptCen, dRad)) { + // creo l'elica + PtrOwner pArc( CreateCurveArc()) ; if ( IsNull( pArc) || ! pArc->Set( ptCen, vtN, dRad, - vtCen, dAngCen, dDeltaN)) return false ; - // eventuale spezzatura + // eventuale spezzatura if ( bSplitArcs) { PtrOwner pCompo( CreateCurveComposite()) ; if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pArc)) || ! ApproxWithLines( pCompo)) @@ -3677,24 +4337,24 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 return ( AddCurveMove( pCompo, MCH_CL_LEADIN) != GDB_ID_NULL) ; } else { - // emetto l'elica + // emetto l'elica return ( AddCurveMove( pArc, MCH_CL_LEADIN) != GDB_ID_NULL) ; } } - // altrimenti zigzag + // altrimenti zigzag else nType = POCKET_LI_ZIGZAG ; } - // Se zigzag e fattibile lo creo + // Se zigzag e fattibile lo creo if ( nType == POCKET_LI_ZIGZAG) { - // dati dello zigzag + // dati dello zigzag double dDeltaN = ( ptStart - ptP1) * vtN ; int nStep = int( ceil( - dDeltaN / ( m_Params.m_dLiElev + 10 * EPS_SMALL))) ; double dStep = - dDeltaN / nStep ; 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 ( VerifyLeadInZigZag( pCompo, ptPa, ptPb)) { + // verifico se fattibile + if ( VerifyLeadInZigZag( pSrf, 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 ; @@ -3703,14 +4363,14 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 } return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; } - // altrimenti diretto + // altrimenti diretto else nType = POCKET_LI_NONE ; } - // Se a scivolo e fattibile + // Se a scivolo e fattibile if ( nType == POCKET_LI_GLIDE) { if ( pRCrv != nullptr) { - // recupero la parte richiesta della curva di ritorno + // recupero la parte richiesta della curva di ritorno PtrOwner pCrv ; double dLen, dU ; if ( pRCrv->GetLength( dLen) && pRCrv->GetParamAtLength( dLen - m_Params.m_dLiTang, dU)) { @@ -3724,25 +4384,25 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 return false ; } pCrv->SetExtrusion( vtN) ; - // la porto alla giusta quota + // la porto alla giusta quota Point3d ptFin ; pCrv->GetEndPoint( ptFin) ; Vector3d vtMove = ptStart - ptFin ; pCrv->Translate( vtMove) ; - // assegno la corretta pendenza + // assegno la corretta pendenza double dNini = ( ptP1 - ORIG) * vtN ; double dNfin = ( ptStart - ORIG) * vtN ; AdjustCurveSlope( pCrv, dNini, dNfin) ; - // eventuale spezzatura + // eventuale spezzatura if ( bSplitArcs && ! ApproxWithLines( pCrv)) return false ; - // emetto + // emetto return ( AddCurveMove( pCrv) != GDB_ID_NULL) ; } - // altrimenti diretto + // altrimenti diretto else nType = POCKET_LI_NONE ; } - // Se diretto + // Se diretto if ( nType == POCKET_LI_NONE) { Point3d ptCurr = ptP1 ; GetCurrPos( ptCurr) ; @@ -3752,72 +4412,72 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 } return true ; } - // Altrimenti errore + // Altrimenti errore return false ; } //---------------------------------------------------------------------------- bool Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced) + const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced) { - // assegno i parametri + // assegno i parametri int nType = GetLeadOutType() ; if ( bNoneForced || - ( nType == POCKET_LO_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0))) + ( nType == POCKET_LO_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0))) nType = POCKET_LO_NONE ; - // eseguo a seconda del tipo + // eseguo a seconda del tipo switch ( nType) { case POCKET_LO_NONE : - { - // nessuna uscita - ptP1 = ptEnd ; - // determino elevazione su fine uscita - double dEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtN, vtN, GetRadiusForStartEndElevation(), vtN, dEndElev)) - dElev = dEndElev ; - // correzione per punto sotto il grezzo con testa normale da sopra - double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && GetPointUnderRaw( ptP1, vtN, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dElev) ; - return true ; - } + { + // nessuna uscita + ptP1 = ptEnd ; + // determino elevazione su fine uscita + double dEndElev ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtN, vtN, GetRadiusForStartEndElevation(), vtN, dEndElev)) + dElev = dEndElev ; + // correzione per punto sotto il grezzo con testa normale da sopra + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && GetPointUnderRaw( ptP1, vtN, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dElev) ; + return true ; + } case POCKET_LO_GLIDE : - { - // recupero la parte richiesta della curva di ritorno - PtrOwner pCrv ; - double dU ; - if ( pRCrv->GetParamAtLength( m_Params.m_dLoTang, dU)) { - if ( ! pCrv.Set( CreateCurveComposite()) || ! pCrv->AddCurve( pRCrv->CopyParamRange( 0, dU))) - return false ; - } - else { - if ( ! pCrv.Set( pRCrv->Clone())) - return false ; - } - // la porto alla giusta quota - Point3d ptIni ; pCrv->GetStartPoint( ptIni) ; - Vector3d vtMove = ptEnd - ptIni ; - pCrv->Translate( vtMove) ; - Point3d ptFin ; pCrv->GetEndPoint( ptFin) ; - ptFin += vtN * 1.0 ; - pCrv->ModifyEnd( ptFin) ; - // eventuale spezzatura - if ( bSplitArcs && ! ApproxWithLines( pCrv)) + { + // recupero la parte richiesta della curva di ritorno + PtrOwner pCrv ; + double dU ; + if ( pRCrv->GetParamAtLength( m_Params.m_dLoTang, dU)) { + if ( ! pCrv.Set( CreateCurveComposite()) || ! pCrv->AddCurve( pRCrv->CopyParamRange( 0, dU))) return false ; - // emetto - AddCurveMove( pCrv) ; - // determino elevazione su fine uscita - ptP1 = ptFin ; - double dEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtN, vtN, GetRadiusForStartEndElevation(), vtN, dEndElev)) - dElev = dEndElev ; - // correzione per punto sotto il grezzo con testa normale da sopra - double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && GetPointUnderRaw( ptP1, vtN, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dElev) ; - return true ; } + else { + if ( ! pCrv.Set( pRCrv->Clone())) + return false ; + } + // la porto alla giusta quota + Point3d ptIni ; pCrv->GetStartPoint( ptIni) ; + Vector3d vtMove = ptEnd - ptIni ; + pCrv->Translate( vtMove) ; + Point3d ptFin ; pCrv->GetEndPoint( ptFin) ; + ptFin += vtN * 1.0 ; + pCrv->ModifyEnd( ptFin) ; + // eventuale spezzatura + if ( bSplitArcs && ! ApproxWithLines( pCrv)) + return false ; + // emetto + AddCurveMove( pCrv) ; + // determino elevazione su fine uscita + ptP1 = ptFin ; + double dEndElev ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtN, vtN, GetRadiusForStartEndElevation(), vtN, dEndElev)) + dElev = dEndElev ; + // correzione per punto sotto il grezzo con testa normale da sopra + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && GetPointUnderRaw( ptP1, vtN, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, dElev) ; + return true ; + } default : return false ; } @@ -3836,10 +4496,10 @@ Pocketing::GetRadiusForStartEndElevation( void) const bool Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMid, Vector3d& vtMidOrt) { - // recupero il vettore estrusione + // recupero il vettore estrusione Vector3d vtExtr = Z_AX ; pCompo->GetExtrusion( vtExtr) ; - // verifico se tutti i lati sono aperti + // verifico se tutti i lati sono aperti bool bAllOpen = true ; const ICurve* pMyCrv = pCompo->GetFirstCurve() ; while ( pMyCrv != nullptr) { @@ -3849,9 +4509,9 @@ 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 dMaxLen = ( bAllOpen ? 0 : m_TParams.m_dDiam + 2 * GetOffsR() - EPS_SMALL) ; - // ciclo sulle singole curve + // ciclo sulle singole curve bool bFound = false ; const ICurve* pPrevCrv = pCompo->GetLastCurve() ; double dLenPrev = 0 ; @@ -3859,7 +4519,7 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi pPrevCrv->GetLength( dLenPrev) ; const ICurve* pCrv = pCompo->GetFirstCurve() ; while ( pCrv != nullptr) { - // analizzo la curva successiva + // analizzo la curva successiva const ICurve* pNextCrv = pCompo->GetNextCurve() ; bool bNextOk = ( pNextCrv != nullptr) ; if ( ! bNextOk) @@ -3867,9 +4527,9 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi double dLenNext = 0 ; if ( pNextCrv != nullptr && pNextCrv->GetTempProp() == 1) pNextCrv->GetLength( dLenNext) ; - // verifico la curva corrente + // 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) { @@ -3883,12 +4543,12 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi dLenAgg += max( 0., vtEnd * vtNextStart * dLenNext) ; } } - // entità corrente + // entità corrente double dLen = 0 ; if ( pCrv->GetLength( dLen) && dLen + dLenAgg > dMaxLen) { dMaxLen = dLen + dLenAgg ; pCrv->GetMidPoint( ptMid) ; - // vettore ortogonale verso l'esterno (ruotato -90deg rispetto a estrusione) + // vettore ortogonale verso l'esterno (ruotato -90deg rispetto a estrusione) pCrv->GetMidDir( vtMidOrt) ; vtMidOrt.Rotate( vtExtr, 0, -1) ; bFound = true ; @@ -3897,7 +4557,7 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi } else dLenPrev = 0 ; - // vado alla successiva + // vado alla successiva pPrevCrv = pCrv ; pCrv = ( bNextOk ? pNextCrv : nullptr) ; } @@ -3909,22 +4569,22 @@ Pocketing::GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMi bool Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) { - // vettore estrusione + // vettore estrusione Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ; - // calcolo riferimento nel piano della svuotatura + // calcolo riferimento nel piano della svuotatura 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 + // raggio di riferimento per offset double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ; - // estraggo tutte le curve in un vettore + // estraggo tutte le curve in un vettore ICURVEPOVECTOR vpCrvs ; vpCrvs.reserve( pCompo->GetCurveCount()) ; while ( pCompo->GetCurveCount() > 0) vpCrvs.emplace_back( pCompo->RemoveFirstOrLastCurve( false)) ; - // elimino le curve troppo corte (10 epsilon) + // elimino le curve troppo corte (10 epsilon) for ( int i = 0 ; i < int( vpCrvs.size()) ;) { double dLen = 0 ; vpCrvs[i]->GetLength( dLen) ; if ( dLen < 10 * EPS_SMALL) @@ -3932,26 +4592,26 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) else ++ i ; } - // offsetto del raggio le curve aperte - for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { + // offsetto del raggio le curve aperte + for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { if ( vpCrvs[i]->GetTempProp() == 1) - vpCrvs[i]->SimpleOffset( dRad) ; + vpCrvs[i]->SimpleOffset( dRad) ; } - // reinserisco le curve, chiudendo eventuali gap + // reinserisco le curve, chiudendo eventuali gap bool bOpenCurr = false ; double dDiam = 1.05 * m_TParams.m_dDiam + 2 * GetOffsR() ; for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - // stato curve + // stato curve bool bOpenPrev = bOpenCurr ; bOpenCurr = ( vpCrvs[i]->GetTempProp() != 0) ; - // chiudo eventuale gap + // chiudo eventuale gap if ( i > 0) { Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; Point3d ptStart ; vpCrvs[i]->GetStartPoint( ptStart) ; if ( ! AreSamePointEpsilon( ptEnd, ptStart, 10 * EPS_SMALL)) { - // se passo da chiuso ad aperto + // se passo da chiuso ad aperto if ( ! bOpenPrev && bOpenCurr) { - // determino la curva ad amo + // determino la curva ad amo Vector3d vtTg ; pCompo->GetEndDir( vtTg) ; Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; Point3d ptArc = ptEnd + dDiam * vtOrt ; @@ -3963,13 +4623,13 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) pJCrv->AddPoint( ptLine) ; pJCrv->AddLine( ptArc, false) ; pJCrv->AddArcTg( ptEnd, false) ; - // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta + // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta pJCrv->ToLoc( frPocket) ; vpCrvs[i]->ToLoc( frPocket) ; IntersCurveCurve intCC( *pJCrv, *vpCrvs[i]) ; pJCrv->ToGlob( frPocket) ; vpCrvs[i]->ToGlob( frPocket) ; - // taglio opportunamente le curve + // taglio opportunamente le curve IntCrvCrvInfo aInfo ; if ( intCC.GetIntCrvCrvInfo( intCC.GetIntersCount() - 1, aInfo)) { pJCrv->TrimEndAtParam( aInfo.IciA[0].dU) ; @@ -3979,9 +4639,9 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) else pCompo->AddLine( ptStart) ; } - // se passo da aperto a chiuso + // se passo da aperto a chiuso else if ( bOpenPrev && ! bOpenCurr) { - // determino la curva ad amo + // determino la curva ad amo Vector3d vtTg ; vpCrvs[i]->GetStartDir( vtTg) ; Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ; Point3d ptArc = ptStart + dDiam * vtOrt ; @@ -3993,7 +4653,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) pJCrv->AddPoint( ptLine) ; pJCrv->AddLine( ptArc) ; pJCrv->AddArcTg( ptStart) ; - // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta + // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta PtrOwner pLCrv( CreateCurveComposite()) ; if ( IsNull( pLCrv)) return false ; @@ -4006,7 +4666,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) IntersCurveCurve intCC( *pJCrv, *pLCrv) ; pJCrv->ToGlob( frPocket) ; pLCrv->ToGlob( frPocket) ; - // taglio opportunamente le curve + // taglio opportunamente le curve IntCrvCrvInfo aInfo ; if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) { double dUs, dUe ; pCompo->GetDomain( dUs, dUe) ; @@ -4021,40 +4681,41 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) pCompo->AddLine( ptStart) ; } } - // aggiungo la curva + // aggiungo la curva pCompo->AddCurve( ::Release( vpCrvs[i]), true, 10 * EPS_SMALL) ; } - // non dovrebbe esserci un gap, ma meglio prevenire problemi + // non dovrebbe esserci un gap, ma meglio prevenire problemi pCompo->Close() ; return true ; } //---------------------------------------------------------------------------- -bool +bool Pocketing::AdjustContourStart( ICurveComposite* pCompo) -{ - // cerco il tratto lineare più lungo che non sia aperto +{ + // cerco il tratto lineare più lungo int i = 0 ; - int nMax = - 1 ; double dLenMax = 0 ; + int nMax = - 1 ; const ICurve* pCrv = pCompo->GetFirstCurve() ; while ( pCrv != nullptr) { - double dLen ; - if ( pCrv->GetType() == CRV_LINE && pCrv->GetTempProp() == 0 && pCrv->GetLength( dLen) && dLen > dLenMax) { + double dLen = 0 ; + if ( pCrv->GetType() == CRV_LINE && pCrv->GetLength( dLen) && dLen > dLenMax) { dLenMax = dLen ; nMax = i ; } ++ i ; pCrv = pCompo->GetNextCurve() ; } - // se non trovato o troppo corto, cerco il tratto generico più lungo - if ( nMax < 0 || dLenMax < 2 * m_TParams.m_dDiam) { + + // 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() ; while ( pCrv != nullptr) { double dLen ; - if ( pCrv->GetType() != CRV_LINE && pCrv->GetTempProp() == 0 && pCrv->GetLength( dLen) && dLen > dLenMax) { + if ( pCrv->GetType() != CRV_LINE && pCrv->GetLength( dLen) && dLen > dLenMax) { dLenMax = dLen ; nMax = i ; } @@ -4063,47 +4724,76 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo) } } - // sposto inizio + // sposto inizio a metà del tratto più lungo + bool bOk = true ; if ( nMax >= 0) - pCompo->ChangeStartPoint( nMax + 0.5) ; + bOk = pCompo->ChangeStartPoint( nMax + 0.5) ; - return true ; + return bOk ; } + + //---------------------------------------------------------------------------- bool -Pocketing::VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const +Pocketing::VerifyLeadInHelix( const ISurfFlatRegion* pSrf, const Point3d& ptCen, double dRad) const { - // recupero il piano della curva di contorno + // recupero il piano della curva di contorno + ICurve * pCrv = pSrf->GetLoop( 0, 0) ; Point3d ptStart ; - Vector3d vtN ; - if ( pCompo == nullptr || ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) + Vector3d vtN ; + if ( pCrv == nullptr || ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetExtrusion( vtN)) return false ; - // porto il centro sullo stesso piano del contorno + // porto il centro sullo stesso piano del contorno Point3d ptCenL = ptCen - ( ptCen - ptStart) * vtN * vtN ; - // calcolo la distanza del centro dal contorno - double dMinDist ; - return ( DistPointCurve( ptCenL, *pCompo).GetDist( dMinDist) && dMinDist > dRad + 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ; + + // calcolo la distanza del centro da tutti i contorni + DBLVECTOR vMinDist ; + double val ; + for ( int nC = 0 ; nC < pSrf->GetChunkCount() ; nC ++) { + for ( int nL = 0 ; nL < pSrf->GetLoopCount( nC) ; nL ++) { + if ( ! DistPointCurve( ptCenL, *( pSrf->GetLoop( nC, nL))).GetDist( val)) + return false ; + vMinDist.push_back( val) ; + } + } + // cerco la distanza minima + double dMinDist = *min_element( vMinDist.begin(), vMinDist.end()) ; + return ( dMinDist > dRad + 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ; + } //---------------------------------------------------------------------------- bool -Pocketing::VerifyLeadInZigZag( const ICurveComposite* pCompo, const Point3d& ptPa, const Point3d& ptPb) const +Pocketing::VerifyLeadInZigZag( const ISurfFlatRegion* pSrf, const Point3d& ptPa, const Point3d& ptPb) const { - // recupero il piano della curva di contorno + // recupero il piano della curva di contorno + ICurve * pCrv = pSrf->GetLoop( 0, 0) ; Point3d ptStart ; Vector3d vtN ; - if ( pCompo == nullptr || ! pCompo->GetStartPoint( ptStart) || ! pCompo->GetExtrusion( vtN)) + if ( pCrv == nullptr || ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetExtrusion( vtN)) return false ; - // porto i punti sullo stesso piano del contorno + // porto i punti sullo stesso piano del contorno Point3d ptPaL = ptPa - ( ptPa - ptStart) * vtN * vtN ; Point3d ptPbL = ptPb - ( ptPb - ptStart) * vtN * vtN ; - // calcolo la distanza dei due punti dal contorno - double dMinDistPa ; - if ( ! DistPointCurve( ptPaL, *pCompo).GetDist( dMinDistPa)) - return false ; - double dMinDistPb ; - if ( ! DistPointCurve( ptPbL, *pCompo).GetDist( dMinDistPb)) - return false ; + + // calcolo la distanza dei due punti da tutti i contorni + DBLVECTOR vMinDistPa ; + DBLVECTOR vMinDistPb ; + double val ; + for ( int nC = 0 ; nC < pSrf->GetChunkCount() ; nC ++) { + for ( int nL = 0 ; nL < pSrf->GetLoopCount( nC) ; nL++) { + if ( ! DistPointCurve( ptPaL, *( pSrf->GetLoop( nC, nL))).GetDist( val)) + return false ; + vMinDistPa.push_back( val) ; + if ( ! DistPointCurve( ptPbL, *( pSrf->GetLoop( nC, nL))).GetDist( val)) + return false ; + vMinDistPb.push_back( val) ; + } + } + // cerco le distanze minime + double dMinDistPa = *min_element( vMinDistPa.begin(), vMinDistPa.end()) ; + double dMinDistPb = *min_element( vMinDistPb.begin(), vMinDistPb.end()) ; + return ( dMinDistPa > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL && dMinDistPb > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ; -} +} \ No newline at end of file diff --git a/Pocketing.h b/Pocketing.h index 89ec6e3..b544a46 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -18,6 +18,7 @@ #include "ToolData.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EGkSurfFlatRegion.h" //---------------------------------------------------------------------------- class Pocketing : public Machining @@ -71,45 +72,47 @@ class Pocketing : public Machining bool ResetCurveAllTempProp( ICurve* pCurve) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; + bool ProcessPath2( int nPathId, int nPvId, int nClId) ; bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ; 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) ; - bool CalcZigZag( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; - 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) ; - bool AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; - bool CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; - bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound, - ICurveComposite* pCrvLink) ; + bool AddZigZag( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; + bool CalcZigZag( const ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vpCrvs) ; + bool AddOneWay( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; + bool AddSpiralIn( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs, bool bMidOpen, + const Point3d& ptMidOpen, const Vector3d& vtMidOut) ; + bool AddSpiralOut( const ISurfFlatRegion* pSrf, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; + bool CalcSpiral( const ISurfFlatRegion* pSrf, int nReg, bool bSplitArcs, + ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; + bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ISurfFlatRegion * pSrf, + ICurveComposite* pCrvLink) ; + bool CircleSpiral( ISurfFlatRegion* pSrf, bool bSplitArcs, ICRVCOMPOPVECTOR& vOffs, ICurveComposite* pRCrv) ; bool CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad, - bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; + bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr, bool bOutStart) ; + double dElev, double dAppr, bool bOutStart) ; bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) ; + double dElev, double dAppr) ; bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) ; + double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, - double dElev, double dAppr) ; + double dElev, double dAppr) ; bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, - const ICurveComposite* pRCrv, Point3d& ptP1) const ; + const ICurveComposite* pRCrv, Point3d& ptP1) const ; 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) ; + const ISurfFlatRegion* pSrf, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced = false) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced = false) ; + const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced = false) ; double GetRadiusForStartEndElevation( void) const ; bool GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMid, Vector3d& vtMidOut) ; - bool AdjustContourWithOpenEdges( ICurveComposite* pCompo) ; + bool AdjustContourWithOpenEdges( ICurveComposite* pCompo) ; bool AdjustContourStart( ICurveComposite* pCompo) ; - bool VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const ; - bool VerifyLeadInZigZag( const ICurveComposite* pCompo, const Point3d& ptPa, const Point3d& ptPb) const ; + bool VerifyLeadInHelix( const ISurfFlatRegion* pSrf, const Point3d& ptCen, double dRad) const ; + bool VerifyLeadInZigZag( const ISurfFlatRegion* pSrf, const Point3d& ptPa, const Point3d& ptPb) const ; private : double GetSpeed( void) const