From bfe3fc1267cd25b177ff65a9a462ed12940d52e3 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 14 May 2026 15:25:56 +0200 Subject: [PATCH] EgtMachKernel : - In PocketingNT aggiunta gestione per ToolCompensation. --- MachConst.h | 9 + OperUserNotesConst.h | 1 + PocketingNT.cpp | 386 +++++++++++++++++++++++++++++++++++-------- PocketingNT.h | 5 +- SurfFinishing.cpp | 10 +- SurfRoughing.cpp | 2 +- 6 files changed, 334 insertions(+), 79 deletions(-) diff --git a/MachConst.h b/MachConst.h index 354d163..327be26 100644 --- a/MachConst.h +++ b/MachConst.h @@ -190,3 +190,12 @@ const double MIN_ZDIR_VERT_CHSAW = 0.7072 ; static const double ROT1_WEIGHT_DFLT = 1 ; // Valore di default per angolo di apertura del cono di direzioni coincidenti con singolarità static const double SING_CONE_ANG_DFLT = 0.01 ; + +//---------------------------------------------------------------------------- +// Compensazione Raggio Utensile in Macchina +enum { + TOOL_COMPENSATION_PROGRAM = 0, // Compensazione Utensile da Programma + TOOL_COMPENSATION_LENGTH = 1, // Compensazione Lunghezza Utensile in Macchina + TOOL_COMPENSATION_RADIUS = 2, // Compensazione Raggio Utensile in Macchina + TOOL_COMPENSATION_LENGHT_AND_RADIUS = 3 // Compensazione Lunghezza e Raggio Utensile in Macchina +} ; diff --git a/OperUserNotesConst.h b/OperUserNotesConst.h index 6cc91d0..4b1e293 100644 --- a/OperUserNotesConst.h +++ b/OperUserNotesConst.h @@ -53,6 +53,7 @@ static const std::string UN_MAXOPTSIZE = "MaxOptSize" ; static const std::string UN_PROJEXT = "ExtProj" ; static const std::string UN_ADJUSTFEED = "AdjustFeed" ; static const std::string UN_MINFEED = "MinFeed" ; +static const std::string UN_TOOL_COMPENSATION = "ToolCompensation" ; // Solo per Sawing static const std::string UN_DOWNSE = "DownSE" ; diff --git a/PocketingNT.cpp b/PocketingNT.cpp index 7c4bf44..91a2acc 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -100,6 +100,7 @@ static double TOOL_RAD_PTSTART = 20. ; // 2437 = "Error in PocketingNT : not valid Trim Surf" // 2438 = "Error in PocketingNT : not valid Pocketing Volume" // 2439 = "Error in PocketingNT : special apply not calculable" +// 2440 = "Error in PocketingNT : compensation tool LeadIn/LeadOut not computable" // 2451 = "Warning in PocketingNT : Skipped entity (xx)" // 2452 = "Warning in PocketingNT : No pocket" // 2453 = "Warning in PocketingNT : Tool name changed (xx)" @@ -127,6 +128,7 @@ static double TOOL_RAD_PTSTART = 20. ; #define DEBUG_PATH_CL 0 // Debug per valori memorizzati nel percorso del CL #define DEBUG_ZIGZAG_LEADIN 0 // Debug per ZigZag LeadIn #define DEBUG_DOUBLE_PARALLEL 0 // Debug per Pocketing in Doppio con Parallelo +#define DEBUG_TOOL_COMPENSATION 0 // Debug per Tool Compensation #define DEBUG 0 // Debug #if DEBUG_STM_TOPOLOGY || DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_SFR_STEPS || DEBUG_SFR_RAW || DEBUG_SFR_GEO_EXT || \ DEBUG_GLIDE || DEBUG_SAFETY_LINK || DEBUG_FEED || DEBUG_START_POINT || DEBUG_PATH_CL || DEBUG_ZIGZAG_LEADIN || DEBUG_DOUBLE_PARALLEL || \ @@ -4328,66 +4330,97 @@ PocketingNT::GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) //---------------------------------------------------------------------------- bool PocketingNT::CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath, - const Vector3d& vtTool, bool bHolePocketing, bool bInVsOut, ICurveComposite* pCrvGlide) + const Vector3d& vtTool, bool bHolePocketing, const Point3d& ptHoleDest, bool bToolCompensation, bool bInVsOut, + ICurveComposite* pCrvGlide) { /* Funzione per il calcolo della curva a sciovolo (piana) in entrata o in uscita pCrvGlide = nullptr */ // controllo dei parametri - if ( pCrvPath == nullptr || ! pCrvPath->IsValid() || - pCrvGlide == nullptr) + if ( pCrvPath == nullptr || ! pCrvPath->IsValid() || pCrvGlide == nullptr) return false ; // se caso speciale curva a spirale if ( bHolePocketing) { - Point3d ptStart ; pCrvPath->GetStartPoint( ptStart) ; - Point3d ptEnd ; pCrvPath->GetEndPoint( ptEnd) ; - if ( ! AreSamePointApprox( ptStart, ptEnd)) { - Vector3d vtStart ; pCrvPath->GetStartDir( vtStart) ; - PtrOwner pArc( CreateCurveArc()) ; - if ( IsNull( pArc) || ! pArc->Set2PVN( ptStart, ptEnd, - vtStart, vtTool)) { - m_pMchMgr->SetLastError( 2420, "Error in Pocketing : Return toolpath not computable") ; - return false ; - } - // inverto - pArc->Invert() ; - // definisco la curva per lo scivolo - PtrOwner pCrvGlideTmp( CreateCurveComposite()) ; - if ( IsNull( pCrvGlideTmp) || ! pCrvGlideTmp->AddCurve( Release( pArc))) - return false ; - // calcolo la curva in base ai parametri - double dLen = 0. ; pCrvGlideTmp->GetLength( dLen) ; - double dParS, dParE ; pCrvGlideTmp->GetDomain( dParS, dParE) ; - double dU ; - // se LeadIn a scivolo, recupero il parametro sulla curva - if ( bInVsOut) { - if ( GetLeadInType() == POCKET_LI_GLIDE) { - if ( ! pCrvGlideTmp->GetParamAtLength( dLen - m_Params.m_dLiTang, dU)) - dU = 0. ; - pCrvGlide->AddCurve( pCrvGlideTmp->CopyParamRange( dU, dParE)) ; + // se percorso normale, allora definisco la sipirale e la Guida + if ( ! bToolCompensation) { + Point3d ptStart ; pCrvPath->GetStartPoint( ptStart) ; + Point3d ptEnd ; pCrvPath->GetEndPoint( ptEnd) ; + if ( ! AreSamePointApprox( ptStart, ptEnd)) { + Vector3d vtStart ; pCrvPath->GetStartDir( vtStart) ; + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc) || ! pArc->Set2PVN( ptStart, ptEnd, - vtStart, vtTool)) { + m_pMchMgr->SetLastError( 2420, "Error in Pocketing : Return toolpath not computable") ; + return false ; } - else - dU = dParE ; - // calcolo la curva di ritorno - PtrOwner pCrvRet( ConvertCurveToComposite( pCrvGlideTmp->CopyParamRange( dParS, dU))) ; - if ( ! IsNull( pCrvRet) && pCrvRet->IsValid()) { - if ( ! PathInfo.pCrvRet.Set( Release( pCrvRet))) - return false ; - } - } - // Se LeadOut a scivolo - else { - if ( GetLeadOutType() == POCKET_LO_GLIDE) { - if ( ! pCrvGlideTmp->GetParamAtLength( m_Params.m_dLoTang, dU)) + // inverto + pArc->Invert() ; + // definisco la curva per lo scivolo + PtrOwner pCrvGlideTmp( CreateCurveComposite()) ; + if ( IsNull( pCrvGlideTmp) || ! pCrvGlideTmp->AddCurve( Release( pArc))) + return false ; + // calcolo la curva in base ai parametri + double dLen = 0. ; pCrvGlideTmp->GetLength( dLen) ; + double dParS, dParE ; pCrvGlideTmp->GetDomain( dParS, dParE) ; + double dU ; + // se LeadIn a scivolo, recupero il parametro sulla curva + if ( bInVsOut) { + if ( GetLeadInType() == POCKET_LI_GLIDE) { + if ( ! pCrvGlideTmp->GetParamAtLength( dLen - m_Params.m_dLiTang, dU)) + dU = 0. ; + pCrvGlide->AddCurve( pCrvGlideTmp->CopyParamRange( dU, dParE)) ; + } + else dU = dParE ; - pCrvGlide->AddCurve( pCrvGlideTmp->CopyParamRange( dParS, dU)) ; - if ( ! pCrvGlide->IsValid()) + // calcolo la curva di ritorno + PtrOwner pCrvRet( ConvertCurveToComposite( pCrvGlideTmp->CopyParamRange( dParS, dU))) ; + if ( ! IsNull( pCrvRet) && pCrvRet->IsValid()) { + if ( ! PathInfo.pCrvRet.Set( Release( pCrvRet))) + return false ; + } + } + // Se LeadOut a scivolo + else { + if ( GetLeadOutType() == POCKET_LO_GLIDE) { + if ( ! pCrvGlideTmp->GetParamAtLength( m_Params.m_dLoTang, dU)) + dU = dParE ; + pCrvGlide->AddCurve( pCrvGlideTmp->CopyParamRange( dParS, dU)) ; + if ( ! pCrvGlide->IsValid()) + return false ; + } + } + } + // non c'è bisogno di verificare nulla con la regione limite + return true ; + } + // se percorso di compensazione, allora la spirale di ritorno parte dal bordo esterno + else { + // se non ho un riferimento valido, non faccio nulla ( sono al percorso a spirale), quindi devo andare al percorso in + // compensazione. Questo passaggio lo posso fare semplicemente raccordandomi, non ho bisogno di calcolare curve di ritorno + if ( ! ptHoleDest.IsValid()) + return true ; + // se ho un riferimento valido, allora posso ricreare l'arco di ritorno + Point3d ptStart ; pCrvPath->GetEndPoint( ptStart) ; // fine del tratto rettilineo in uscita + Point3d ptEnd = ptHoleDest ; // punto dove devo arrivare ( inizio della spirale) + int nCrvCnt = pCrvPath->GetCurveCount() ; + if ( ! AreSamePointApprox( ptStart, ptEnd) && nCrvCnt > 2) { + const ICurve* pCrvLastArc = pCrvPath->GetCurve( nCrvCnt - 2) ; + if ( pCrvLastArc != nullptr && pCrvLastArc->IsValid()) { + Vector3d vtStart ; pCrvLastArc->GetEndDir( vtStart) ; + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc) || ! pArc->Set2PVN( ptStart, ptEnd, vtStart, vtTool)) { + m_pMchMgr->SetLastError( 2420, "Error in Pocketing : Return toolpath not computable") ; + return false ; + } + PtrOwner pCompoRet( CreateCurveComposite()) ; + if ( IsNull( pCompoRet) || ! pCompoRet->AddCurve( Release( pArc)) || + ! PathInfo.pCrvRet.Set( Release( pCompoRet))) return false ; } } + // non c'è bisogno di verificare nulla con la regione limite + return true ; } - // non c'è bisogno di verificare nulla con la regione limite - return true ; } // se regione di svuotatura generica else { @@ -4601,6 +4634,11 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) } } + // verifico se presente parametro Tool Compensation + int nToolCompensation = -1 ; + bool bToolCompensation = ( GetValInNotes( m_Params.m_sUserNotes, UN_TOOL_COMPENSATION, nToolCompensation) && + ( nToolCompensation == TOOL_COMPENSATION_RADIUS || nToolCompensation == TOOL_COMPENSATION_LENGHT_AND_RADIUS)) ; + // determino il SideStep double dSideStep = ( ! bPolishing ? GetSideStep() : m_Params.m_dSideStep) ; // determino se Conventional Milling o Climb Milling per curve singole @@ -4608,14 +4646,14 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) m_Params.m_nSubType == POCKET_ONEWAY || m_Params.m_nSubType == POCKET_CONFORMAL_ONEWAY) ; // scorro gli indici delle superfici - for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) { + for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) { // calcolo i percorsi di Pocketing ( o di lucidatura se richiesto) ICRVCOMPOPOVECTOR vCrvPaths ; if ( ! CalcPocketing( vStepInfo[i].pSfrPock, m_TParams.m_dDiam / 2, GetOffsR(), dSideStep, m_Params.m_dSideAngle, m_dOpenMinSafe, m_Params.m_nSubType, true, true, m_Params.m_bInvert, false, bConventionalMilling, true, bAdjustFeed, ptStartRef, vStepInfo[i].pSfrLimit, bAllOffset, dMaxOptSize, GetLeadInType(), m_Params.m_dLiTang, m_Params.m_dLiElev, GetLeadOutType(), m_Params.m_dLoTang, - bPolishing, m_Params.m_dEpicyclesRad, m_Params.m_dEpicyclesDist, vCrvPaths)) { + bPolishing, m_Params.m_dEpicyclesRad, m_Params.m_dEpicyclesDist, bToolCompensation, vCrvPaths)) { m_pMchMgr->SetLastError( 3028, "Error in PocketingNT : Error in CalcPocketing") ; return false ; } @@ -4670,12 +4708,15 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) vStepInfo[i].vPaths[j].bIsZigZagOneWayBorder = ( vCrvPaths[j]->GetCurveCount() > 0 && ( m_Params.m_nSubType == POCKET_SUB_ONEWAY || m_Params.m_nSubType == POCKET_SUB_ZIGZAG) && vCrvPaths[j]->GetTempProp( 0) == TEMP_PROP_BORDER_CURVE) ; + // controllo se è una curva di compensazione utensile + vStepInfo[i].vPaths[j].bToolCompensation = ( vCrvPaths[j]->GetCurveCount() > 0 && + vCrvPaths[j]->GetTempProp( 0) == TEMP_PROP_CONTOUR_BORDER) ; // assegno il percorso if ( ! vStepInfo[i].vPaths[j].pCrvPath.Set( vCrvPaths[j])) return false ; } // definisco il nuovo punto di riferimento per il percorso successivo - // Se caso ottimizzato a spirale + // --------------------- Se caso ottimizzato a spirale --------------------- if ( ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle) { // Se entrata da fuori, ricomincio dall'esterno if ( vStepInfo[i].vPaths[0].bOutStart) @@ -4689,8 +4730,13 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) } } // altrimenti rimane fisso al punto iniziale del percorso precedente - else - vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartRef) ; + else { + // se percorso di correzione, e caso precedente a spirale, non aggiorno il percorso + if ( bToolCompensation && ssize( vStepInfo[i].vPaths) == 2 && vStepInfo[i].vPaths[0].bOptCirle) + ; // lascio invariato + else + vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartRef) ; + } // aggiorno la progressBar ExeProcessEvents( 50 + i * 50 / ssize( vStepInfo), 0) ; } @@ -4698,7 +4744,8 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) // controllo se la svuotatura è riferita ad un foro chiuso bool bHolePocketing = true ; for ( int i = 0 ; i < ssize( vStepInfo) && bHolePocketing ; ++ i) { - bHolePocketing = ( ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle && + int nPaths = ( bToolCompensation ? 2 : 1) ; + bHolePocketing = ( ssize( vStepInfo[i].vPaths) == nPaths && vStepInfo[i].vPaths[0].bOptCirle && ! vStepInfo[i].vPaths[0].bOutStart && ! vStepInfo[i].vPaths[0].bOutEnd) ; } // se foro chiuso ed entrata ad elica, aggiusto il raggio massimo @@ -4712,28 +4759,51 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) } } } - + + // se ho percorsi di compensazione utensile, devo aggiungere all'inizio e alla fine della curva due tratti lineari perpendicolari ad + // essa, in questo modo consento alla macchina di cambiare modalità ( questi tratti sono obbligatori) + if ( bToolCompensation) { + for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) { + for ( int j = 0 ; j < ssize( vStepInfo[i].vPaths) ; ++ j) { + if ( vStepInfo[i].vPaths[j].bToolCompensation && + ! IsNull( vStepInfo[i].vPaths[j].pCrvPath) && vStepInfo[i].vPaths[j].pCrvPath->IsValid()) { + if ( ! AddTangentLinesForToolCompensation( vStepInfo[i].vPaths[j].pCrvPath, m_vtTool, vStepInfo[i].pSfrLimit)) + return false ; + } + } + } + } + // calcolo la curva di ritorno ( se necessaria) for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) { for ( int j = 0 ; j < ssize( vStepInfo[i].vPaths) ; ++ j) { - if ( GetLeadInType() == POCKET_LI_GLIDE || bHolePocketing) { - PtrOwner pCrvGlideIn( CreateCurveComposite()) ; - if ( IsNull( pCrvGlideIn) || - ! CalcRetCurve( vStepInfo[i].vPaths[j], vStepInfo[i], vStepInfo[i].vPaths[j].pCrvPath, - vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, true, pCrvGlideIn)) { - m_pMchMgr->SetLastError( 2415, "Error in PocketingNT : LeadIn not computable") ; - return false ; + if ( ( GetLeadInType() == POCKET_LI_GLIDE || bHolePocketing)) { + Point3d ptHoleDest = P_INVALID ; + if ( bToolCompensation) { + if ( bHolePocketing && j == 1) + vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptHoleDest) ; } - if ( ! IsNull( pCrvGlideIn) && pCrvGlideIn->IsValid()) + PtrOwner pCrvGlideIn( CreateCurveComposite()) ; + if ( ! bToolCompensation || ( bToolCompensation && bHolePocketing && j == 1)) { + if ( IsNull( pCrvGlideIn) || + ! CalcRetCurve( vStepInfo[i].vPaths[j], vStepInfo[i], vStepInfo[i].vPaths[j].pCrvPath, + vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, ptHoleDest, bToolCompensation, true, pCrvGlideIn)) { + m_pMchMgr->SetLastError( 2415, "Error in PocketingNT : LeadIn not computable") ; + return false ; + } + } + if ( ! IsNull( pCrvGlideIn) && pCrvGlideIn->IsValid()) { if ( ! vStepInfo[i].vPaths[j].pCrvGlideIn.Set( Release( pCrvGlideIn))) return false ; + m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vStepInfo[i].vPaths[j].pCrvGlideIn->Clone()) ; + } } // se uscita a scivolo - if ( GetLeadOutType() == POCKET_LO_GLIDE || bHolePocketing) { + if ( ( GetLeadOutType() == POCKET_LO_GLIDE || bHolePocketing) && ! bToolCompensation) { PtrOwner pCrvGlideOut( CreateCurveComposite()) ; if ( IsNull( pCrvGlideOut) || ! CalcRetCurve( vStepInfo[i].vPaths[j], vStepInfo[i], vStepInfo[i].vPaths[j].pCrvPath, - vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, false, pCrvGlideOut)) { + vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, P_INVALID, false, bToolCompensation, pCrvGlideOut)) { m_pMchMgr->SetLastError( 2416, "Error in PocketingNT : LeadOut not computable") ; return false ; } @@ -4775,12 +4845,18 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) //---------------------------------------------------------------------------- bool -PocketingNT::ManageSmoothLink( const PathInfoPO& currPath, const PathInfoPO& nextPath, bool bSamePlane, +PocketingNT::ManageSmoothLink( const PathInfoPO& currPath, const PathInfoPO& nextPath, bool bSamePlane, bool& bSmoothEnd, bool& bForceLinear) { // definizione smusso finale a seconda del tipo di lavorazioni bSmoothEnd = true ; bForceLinear = false ; + if ( nextPath.bToolCompensation) { + bSmoothEnd = false ; + bForceLinear = false ; + return true ; + } + switch ( m_Params.m_nSubType) { case POCKET_SUB_SPIRALIN : @@ -5198,7 +5274,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou } } // altrimenti - else if ( ! currPath.bOutStart) + else if ( ! currPath.bToolCompensation && ! currPath.bOutStart) ptP1 += vtTool * ( currStep.dRelativeDepth) ; } // altrimenti, l'elevazione va nell'attacco anche nel caso in cui ho una direzione di 'Escape' @@ -5244,9 +5320,10 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou #endif AddLinearMove( ptP1, bSplitArcs) ; } - bool bNoneForced = ( currPath.bOutStart || currPath.bSingleCrv || - ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && ! currPath.bIsZigZagOneWayBorder) || - ( m_Params.m_nSubType == POCKET_SUB_ONEWAY && ! currPath.bIsZigZagOneWayBorder)) ; + bool bNoneForced = ( currPath.bToolCompensation || + currPath.bOutStart || currPath.bSingleCrv || + ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && ! currPath.bIsZigZagOneWayBorder) || + ( m_Params.m_nSubType == POCKET_SUB_ONEWAY && ! currPath.bIsZigZagOneWayBorder)) ; if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, currStep.pSfrPock, Get( currPath.pCrvGlideIn), Get( currPath.pCrvZigZagIn), ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT ? m_Params.m_bInvert : ! m_Params.m_bInvert), bSplitArcs, bNoneForced, false)) { @@ -5274,6 +5351,12 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou if ( AddCurveMove( pCurve, bSplitArcs) == GDB_ID_NULL) return false ; } + // se percorso di compensazione + if ( currPath.bToolCompensation) { + int nId = m_pGeomDB->GetLastInGroup( m_nPathId) ; + if ( ! AssignPropsToCamDataForToolCompensation( nId, ( k == 0), ( k == nMaxInd), m_Params.m_bInvert)) + return false ; + } // se ultima entità if ( k == nMaxInd) { @@ -5321,6 +5404,8 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou } else { // aggiungo retroazione finale + if ( currPath.bToolCompensation && dLastElev < EPS_SMALL) + dLastElev = currStep.dDepth ; if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dLastElev, dAppr, bSplitArcs)) { m_pMchMgr->SetLastError( 3015, "Error in PocketingNT : Retract not computable") ; return false ; @@ -5355,7 +5440,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou PtrOwner pCrvLink( CreateCurveComposite()) ; if ( IsNull( pCrvLink)) return false ; - // se ho una curva di ritorno, allora uso quella + // se ho una curva di ritorno, allora uso quella ( non per ToolCompensation) if ( currPath.pCrvRet != nullptr && currPath.pCrvRet->IsValid()) { pCrvLink->CopyFrom( currPath.pCrvRet) ; bSafeLimit = true ; @@ -5375,10 +5460,14 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou if ( bSafeLimit) { // e sullo stesso piano di pocketing if ( bSamePlane) { - if ( ( ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) && - ! vStepInfo[i].vPaths[j+1].bOutStart) || - ( m_Params.m_nSubType != POCKET_SUB_SPIRALIN && m_Params.m_nSubType != POCKET_SUB_SPIRALOUT && - m_Params.m_nSubType != POCKET_CONFORMAL_ZIGZAG && m_Params.m_nSubType != POCKET_SUB_CONFORMAL_ONEWAY)) { + // se ToolCompensation allora rimango nel materiale + if ( PathToGo.bToolCompensation) { + ; // non cambio nulla + } + else if ( ( ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) && + ! vStepInfo[i].vPaths[j+1].bOutStart) || + ( m_Params.m_nSubType != POCKET_SUB_SPIRALIN && m_Params.m_nSubType != POCKET_SUB_SPIRALOUT && + m_Params.m_nSubType != POCKET_CONFORMAL_ZIGZAG && m_Params.m_nSubType != POCKET_SUB_CONFORMAL_ONEWAY)) { dCurrElev += currStep.dRelativeDepth ; dNextElev = dCurrElev ; } @@ -6676,6 +6765,159 @@ PocketingNT::CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const V return true ; } +//---------------------------------------------------------------------------- +bool +PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit) const +{ + // Verifico che la curva sia valida + if ( pCompoPath == nullptr || ! pCompoPath->IsValid()) + return false ; + + // Porto tutto in un piano XY locale + Point3d ptStart ; pCompoPath->GetStartPoint( ptStart) ; + Frame3d frLoc ; + if ( ! frLoc.Set( ptStart, vtTool)) + return false ; + PtrOwner pCompoPathLoc( CloneCurveComposite( pCompoPath)) ; + if ( IsNull( pCompoPathLoc) || ! pCompoPathLoc->IsValid() || ! pCompoPathLoc->ToLoc( frLoc)) + return false ; + PtrOwner pSfrLimitLocUB( nullptr) ; // Upper Bound + if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) { + if ( ! pSfrLimitLocUB.Set( CloneSurfFlatRegion( pSfrLimit)) || ! pSfrLimitLocUB->IsValid() || ! pSfrLimitLocUB->ToLoc( frLoc)) + return false ; + // Effettuo un Offset alla superficie, definendo la regione che il centro utensile non deve varcare + if ( ! pSfrLimitLocUB->Offset( m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, ICurve::OFF_FILLET)) + return false ; + } + + #if DEBUG_TOOL_COMPENSATION + int nGrpLocId = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + m_pGeomDB->SetName( nGrpLocId, "LOCAL_COMPENSATION") ; + int nLayId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpLocId, GLOB_FRM) ; + m_pGeomDB->SetName( nLayId, "LOCAL_COMPENSATION") ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCompoPathLoc->Clone()) ; + m_pGeomDB->SetMaterial( nId, BLUE) ; + if ( ! IsNull( pSfrLimitLocUB) && pSfrLimitLocUB->IsValid()) { + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pSfrLimitLocUB->Clone()) ; + m_pGeomDB->SetMaterial( nId, GRAY) ; + } + #endif + + // Calcolo tratto lineare Iniziale e Finale + const double EXTRA_LEN = 2. ; + const double LEN_LINE = EXTRA_LEN ; + + double dRotAngle = 0. ; + // se siamo in lavorazione SpiralIn, la curva è orientata come il contorno ( a meno di una inversione) + if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN) + dRotAngle = ( m_Params.m_bInvert ? - ANG_RIGHT : ANG_RIGHT) ; + // se siamo in lavorazione SpiralOut, la curva è orientata inversamente rispetto al contorno + else if ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) + dRotAngle = ( m_Params.m_bInvert ? ANG_RIGHT : - ANG_RIGHT) ; + // per le altre lavorazioni, tengo le curve orientate come i bordi ( si può estendere questo caso) + else + dRotAngle = ( m_Params.m_bInvert ? - ANG_RIGHT : ANG_RIGHT) ; + + pCompoPathLoc->GetStartPoint( ptStart) ; + Vector3d vtStart ; pCompoPathLoc->GetStartDir( vtStart) ; + Vector3d vtOut = vtStart ; vtOut.Rotate( Z_AX, dRotAngle) ; + PtrOwner pLineS( CreateCurveLine()) ; + if ( IsNull( pLineS) || ! pLineS->Set( ptStart + vtOut * LEN_LINE, ptStart)) + return false ; + #if DEBUG_TOOL_COMPENSATION + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLineS->Clone()) ; + m_pGeomDB->SetMaterial( nId, AQUA) ; + #endif + if ( ! IsNull( pSfrLimitLocUB) && pSfrLimitLocUB->IsValid()) { + CRVCVECTOR ccClass ; + if ( ! pSfrLimitLocUB->GetCurveClassification( *pLineS, EPS_SMALL, ccClass) || + ! ( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT)) { + m_pMchMgr->SetLastError( 2440, "Error in PocketingNT : compensation tool LeadIn/LeadOut not computable") ; + return false ; + } + } + + Point3d ptEnd ; pCompoPathLoc->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; pCompoPathLoc->GetEndDir( vtEnd) ; + vtOut = vtEnd ; vtOut.Rotate( Z_AX, dRotAngle) ; + PtrOwner pLineE( CreateCurveLine()) ; + if ( IsNull( pLineE) || ! pLineE->Set( ptEnd, ptEnd + vtOut * LEN_LINE)) + return false ; + #if DEBUG_TOOL_COMPENSATION + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLineE->Clone()) ; + m_pGeomDB->SetMaterial( nId, AQUA) ; + #endif + if ( ! IsNull( pSfrLimitLocUB) && pSfrLimitLocUB->IsValid()) { + CRVCVECTOR ccClass ; + if ( ! pSfrLimitLocUB->GetCurveClassification( *pLineE, EPS_SMALL, ccClass) || + ! ( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT)) { + m_pMchMgr->SetLastError( 2440, "Error in PocketingNT : compensation tool LeadIn/LeadOut not computable") ; + return false ; + } + } + + // Aggiungo il tratto lineare all'inizio e alla fine + Point3d ptSLoc ; pLineS->GetStartPoint( ptSLoc) ; + Point3d ptELoc ; pLineE->GetEndPoint( ptELoc) ; + Point3d ptSGlob = GetToGlob( ptSLoc, frLoc) ; + Point3d ptEGlob = GetToGlob( ptELoc, frLoc) ; + if ( ! pCompoPath->AddLine( ptSGlob, false) || ! pCompoPath->AddLine( ptEGlob, true)) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +PocketingNT::AssignPropsToCamDataForToolCompensation( int nId, bool bLineIn, bool bLineOut, bool bToolAtLeft) +{ + // recupero l'entità geometrica corrente + IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nId) ; + if ( pGeoObj == nullptr) + return false ; + + // se tratto iniziale + if ( bLineIn) { + // deve essere necesariamente un tratto lineare + if ( pGeoObj->GetType() != CRV_LINE) + return false ; + CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nId)) ; + if ( pCamData == nullptr) + return false ; + pCamData->SetFeed( GetStartFeed()) ; // Feed Iniziale + // Flag 141 o 142 a seconda della posizione dell'utensile rispetto al percorso + m_pGeomDB->SetInfo( nId, KEY_TRC, bToolAtLeft ? 141 : 142) ; + // Modifica colore + m_pGeomDB->SetMaterial( nId, GREEN) ; + } + // se tratto finale + else if ( bLineOut) { + // deve essere necessariamente un tratto lineare + if ( pGeoObj->GetType() != CRV_LINE) + return false ; + CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nId)) ; + if ( pCamData == nullptr) + return false ; + pCamData->SetFeed( GetEndFeed()) ; // Feed Finale + // Flag 140 per annullare la compensazione attivata precedentemente + m_pGeomDB->SetInfo( nId, KEY_TRC, 140) ; + // Modifica del colore + m_pGeomDB->SetMaterial( nId, GREEN) ; + } + // se tratto generico + else { + CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nId)) ; + if ( pCamData == nullptr) + return false ; + // Flag 41 o 42 a seconda della posizione dell'utensile riseptto al percorso + m_pGeomDB->SetInfo( nId, KEY_TRC, bToolAtLeft ? 41 : 42) ; + // Modifica del colore + m_pGeomDB->SetMaterial( nId, GREEN) ; + } + + return true ; +} + // debug functions //---------------------------------------------------------------------------- void diff --git a/PocketingNT.h b/PocketingNT.h index e67528e..146ab7e 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -30,6 +30,7 @@ struct PathInfoPO { bool bOptTrap ; // flag per casi ottimizzati a trapezio ( per Spiral) bool bOptCirle ; // flag per casi ottimizzati a Spirale ( per Spiral) bool bIsZigZagOneWayBorder ; // curve di bordo dei lati chiusi ( per ZigZag e OneWay) + bool bToolCompensation ; // curva di bordo per compensazione utensile PtrOwner pCrvPath ; // percorso del centro utensile PtrOwner pCrvGlideIn ; // curva per LeadIn a guida PtrOwner pCrvGlideOut ; // curva per LeadOut a guida @@ -135,7 +136,7 @@ class PocketingNT : public Machining bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ; bool CalcPaths( STEPINFOPOVECTOR& vStepInfo) ; bool CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath, - const Vector3d& vtTool, bool bHolePocketing, bool bInVsOut, ICurveComposite* pCrvGlide) ; + const Vector3d& vtTool, bool bHolePocketing, const Point3d& ptHoleDest, bool bToolCompensation, bool bInVsOut, ICurveComposite* pCrvGlide) ; bool AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, Point3d& ptPockStart, Point3d& ptPockEnd) ; double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRightStartFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; @@ -182,6 +183,8 @@ class PocketingNT : public Machining const INTVECTOR& vLeadOutId, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool, bool bSplitArcs, double dMinFeed) ; double GetDoubleLastStep( void) ; + bool AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit) const ; + bool AssignPropsToCamDataForToolCompensation( int nId, bool bLineIn, bool bLineOut, bool bToolAtLeft) ; // debug void DebugDrawSfr( const ISurfFlatRegion* pSfr, bool bUniform, int nlayer = GDB_ID_ROOT) ; void DebugDrawLoop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ; diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 2344fcd..6f3a33c 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -2279,7 +2279,7 @@ SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_ZIGZAG, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, - GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., vpCrvs)) { + GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -2307,7 +2307,7 @@ SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_ONEWAY, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, - GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., vpCrvs)) { + GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -2335,7 +2335,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrCnt, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., nType, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, - GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., vpCrvs)) { + GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -4780,7 +4780,7 @@ SurfFinishing::GetOffsetCurvesFromPencilProjection( const ICRVCOMPOPOVECTOR& vCr if ( ! CalcPocketing( pSfrChunk, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., POCKET_SUB_ZIGZAG, false, false, m_Params.m_bInvert, true, true, false, false, P_INVALID, nullptr, true, INFINITO, GetLeadInType(), m_Params.m_dLiTang, 0., - GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., vCrvZigZag)) + GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vCrvZigZag)) return false ; // inserisco le curve ricavate for ( auto& pCompo : vCrvZigZag) { @@ -5478,7 +5478,7 @@ SurfFinishing::CalcOptimalZigZagCurves( const ISurfFlatRegion* pSfrLoc, const Fr ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrChunk, m_TParams.m_dDiam / 2., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., nSubType, false, false, false, true, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, - GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., vpCrvs)) { + GetLeadInType(), m_Params.m_dLiTang, 0., GetLeadOutType(), m_Params.m_dLoTang, false, 0., 0., false, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index a949065..edce84d 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -3045,7 +3045,7 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf m_Params.m_dSideAngle, 5., vStepInfo[nInd].nSubType, true, true, vStepInfo[nInd].bInverted, false, bConventionalMilling, true, true, ptEndLastPath, vStepInfo[nInd].pSfrLimit, false, m_Params.m_dSideStep, GetLeadInType(), m_Params.m_dLiTang, m_Params.m_dLiElev, GetLeadOutType(), m_Params.m_dLoTang, - false, 0., 0., vCrvPaths)) { + false, 0., 0., false, vCrvPaths)) { if ( vStepInfo[nInd].bIsExtraStep) { string sWarn = "Warning in SurfRoughing : CalcPocketing failed with substep (" + ToString( vStepInfo[nInd].dDepth, 1) + ")" ; m_pMchMgr->SetWarning( 3055, sWarn) ;