From c18e80a70d88d62bf257231eacbb40f2d4d87346 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 5 Dec 2025 18:31:35 +0100 Subject: [PATCH] - MachiningLib, PreSimulationLib e FACEBYBLADE modificate per introduzione check finecorsa (da completare) e check attacchi --- LuaLibs/MachiningLib.lua | 96 ++++++++++++++++++++++++++---------- LuaLibs/PreSimulationLib.lua | 14 ++++-- StrategyLibs/FACEBYBLADE.lua | 55 +++++++++++---------- 3 files changed, 111 insertions(+), 54 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index d857dde..a53f3a8 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -304,7 +304,7 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters) error( 'TestEngagement : unknown engagement') end - -- se l'angolo non può essere raggiunto dall'utensile si esce subito + -- se l'angolo non può essere raggiunto dall'utensile la lavorazione non è fattibile if IsFaceZOutOfRange( vtHead, Tool) then return false end @@ -318,31 +318,85 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters) dDepthToMachine = dDepthToMachine } - local bCollisionFound, bMoveAfterSplit = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, OptionalParameters) + -- lavorazione oltre le corse: non fattibile + local bOutOfStroke = PreSimulationLib.CheckOutOfStroke() + if bOutOfStroke then + return false + end - return not bCollisionFound, bMoveAfterSplit + -- lavorazione in collisione con il pezzo: non fattibile + local bCollisionFound, bMoveAfterSplit = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, OptionalParameters) + if bCollisionFound then + return false + end + + -- check attacchi + local bNeedTangentLeadInOut = false + local bOutOfStrokePerpendicular = PreSimulationLib.CheckOutOfStroke() -- TODO passare punti custom attacco perpendicolare + + -- attacco perpendicolare oltre le corse: si prova attacco tangenziale + if bOutOfStrokePerpendicular then + + local bOutOfStrokeTangent = PreSimulationLib.CheckOutOfStroke() -- TODO passare punti custom attacco tangenziale + + -- entrambi gli attacchi oltre le corse: lavorazione non fattibile + if bOutOfStrokeTangent then + + return false + + -- check collisione attacco tangenziale + else + local bCollisionFoundTangent, bMoveAfterSplitTangent = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, OptionalParameters) -- TODO passare punti custom attacco tangenziale + + -- attacco perpendicolare oltre le corse e attacco tangenziale in collisione: lavorazione non fattibile + if bCollisionFoundTangent then + + return false + + -- obbligatorio attacco tangenziale + else + bMoveAfterSplit = bMoveAfterSplit or bMoveAfterSplitTangent + bNeedTangentLeadInOut = true + end + end + end + + -- arrivati qui la lavorazione è fattibile: si restituisce se è necessario farla dopo separazione e se serve attacco tangenziale + return true, bMoveAfterSplit, bNeedTangentLeadInOut end ------------------------------------------------------------------------------------------------------------- --- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) +-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e se è necessario un attacco tangenziale -- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) -- TODO da gestire riduzione percorso function MachiningLib.GetBladeEngagement( Parameters, OptionalParameters) + local Engagement + -- test lavorazione faccia in modo standard (no DownUp) - local bIsEngagementOk, bMoveAfterSplit = TestEngagement( 'Standard', Parameters, OptionalParameters) + local bIsEngagementOk, bMoveAfterSplit, bNeedTangentLeadInOut = TestEngagement( 'Standard', Parameters, OptionalParameters) if bIsEngagementOk then - return true, 'Standard', bMoveAfterSplit + Engagement = { + sBladeEngagement = 'Standard', + bMoveAfterSplit = bMoveAfterSplit, + bNeedTangentLeadInOut = bNeedTangentLeadInOut + } + return true, Engagement end -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile - bIsEngagementOk, bMoveAfterSplit = TestEngagement( 'DownUp', Parameters, OptionalParameters) + bIsEngagementOk, bMoveAfterSplit, bNeedTangentLeadInOut = TestEngagement( 'DownUp', Parameters, OptionalParameters) if bIsEngagementOk then - return true, 'DownUp', bMoveAfterSplit + Engagement = { + sBladeEngagement = 'DownUp', + bMoveAfterSplit = bMoveAfterSplit, + bNeedTangentLeadInOut = bNeedTangentLeadInOut + } + return true, Engagement end return false @@ -495,10 +549,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local nBestToolIndex local dBestToolResidualDepth = 0 - local sCurrentBladeEngagement - local sBestBladeEngagement - local bCurrentMoveAfterSplit - local bBestMoveAfterSplit + local CurrentEngagement + local BestEngagement for i = 1, #TOOLS do local bIsToolCompatible = false @@ -527,7 +579,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) bIsDicing = bIsDicing } TIMER:startElapsed( 'GetBladeEngagement') - bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) + bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) TIMER:stopElapsed( 'GetBladeEngagement') -- orientamento non raggiungibile if not bIsBladeOk then @@ -553,15 +605,13 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL) then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth - sBestBladeEngagement = sCurrentBladeEngagement - bBestMoveAfterSplit = bCurrentMoveAfterSplit + BestEngagement = CurrentEngagement else -- prediligo utensile per tagli lungo vena, se richiesto if bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth - sBestBladeEngagement = sCurrentBladeEngagement - bBestMoveAfterSplit = bCurrentMoveAfterSplit + BestEngagement = CurrentEngagement else -- entrambi completi if dBestToolResidualDepth <= 10 * GEO.EPS_SMALL and dCurrentResidualDepth <= 10 * GEO.EPS_SMALL then @@ -572,15 +622,13 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) GetIndexToolInAvailableToolList( ToolSearchParameters.AvailableToolList, TOOLS[nBestToolIndex].sName) then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth - sBestBladeEngagement = sCurrentBladeEngagement - bBestMoveAfterSplit = bCurrentMoveAfterSplit + BestEngagement = CurrentEngagement end -- si sceglie quello con le performance migliori elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex + 10 * GEO.EPS_SMALL then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth - sBestBladeEngagement = sCurrentBladeEngagement - bBestMoveAfterSplit = bCurrentMoveAfterSplit + BestEngagement = CurrentEngagement end -- entrambi incompleti elseif dBestToolResidualDepth > 10 * GEO.EPS_SMALL and dCurrentResidualDepth > 10 * GEO.EPS_SMALL then @@ -588,8 +636,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if dCurrentResidualDepth > dBestToolResidualDepth then nBestToolIndex = i dBestToolResidualDepth = dCurrentResidualDepth - sBestBladeEngagement = sCurrentBladeEngagement - bBestMoveAfterSplit = bCurrentMoveAfterSplit + BestEngagement = CurrentEngagement end end end @@ -599,8 +646,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) ToolInfo.nToolIndex = nBestToolIndex ToolInfo.dResidualDepth = dBestToolResidualDepth - ToolInfo.sBladeEngagement = sBestBladeEngagement - ToolInfo.bMoveAfterSplit = bBestMoveAfterSplit + ToolInfo.Engagement = BestEngagement return ToolInfo end diff --git a/LuaLibs/PreSimulationLib.lua b/LuaLibs/PreSimulationLib.lua index e135661..4216b6f 100644 --- a/LuaLibs/PreSimulationLib.lua +++ b/LuaLibs/PreSimulationLib.lua @@ -74,6 +74,12 @@ local function GetMachiningPoints( Edge, dDepthToMachine) return MachiningPoints end +------------------------------------------------------------------------------------------------------------- +function PreSimulationLib.CheckOutOfStroke() + + return false +end + ------------------------------------------------------------------------------------------------------------- local function CheckCollisionPoint( ptPointToCheck, vtC, vtHead, PreCollisionData, Part, bCheckOnlyRestlength) @@ -138,7 +144,7 @@ end ------------------------------------------------------------------------------------------------------------- -- controllo collisione con verifica intersezione trimesh e geometrie da macchina -function PreSimulationLib.CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParameters) +local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParameters) -- parametri obbligatori local Edge = MachiningParameters.Edge @@ -230,7 +236,7 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional OptionalParametersCheckCollisionWithAxis.MachiningPoints = OptionalParameters.MachiningPoints or nil -- asse Z si controlla sempre - bCollisionFound, bMoveAfterSplitZ = PreSimulationLib.CheckCollisionWithAxis( 'Z', Parameters, OptionalParametersCheckCollisionWithAxis) + bCollisionFound, bMoveAfterSplitZ = CheckCollisionWithAxis( 'Z', Parameters, OptionalParametersCheckCollisionWithAxis) -- se cubetti in modalità standard (no DownUp), gli assi AB e C si controllano solo con grezzo (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo) if sBladeEngagement == 'Standard' then @@ -238,11 +244,11 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional end if not bCollisionFound then - bCollisionFound, bMoveAfterSplitAB = PreSimulationLib.CheckCollisionWithAxis( 'AB', Parameters, OptionalParametersCheckCollisionWithAxis) + bCollisionFound, bMoveAfterSplitAB = CheckCollisionWithAxis( 'AB', Parameters, OptionalParametersCheckCollisionWithAxis) end if not bCollisionFound then - bCollisionFound, bMoveAfterSplitC = PreSimulationLib.CheckCollisionWithAxis( 'C', Parameters, OptionalParametersCheckCollisionWithAxis) + bCollisionFound, bMoveAfterSplitC = CheckCollisionWithAxis( 'C', Parameters, OptionalParametersCheckCollisionWithAxis) end local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 95967f1..8f9e14d 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -90,11 +90,15 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) LeadOut.dPerpDistance = 0 LeadIn.dTangentDistance = 0 LeadOut.dTangentDistance = 0 + + -- TODO qui dovrebbe essere sempre perpendicolare tranne se bNeedTangentLeadInOut, che il GetBladeEngagement deve settare sempre correttamente per evitare sia messo in casi impropri + -- il problema è che se non è controllato bene dal GetBladeEngagement, che non ha tutte le informazioni(?), si potrebbe incorrere in scelte errate if Machining.bIsStartClosed or Machining.bIsEndClosed or Machining.CloneStepsRadial.nCount > 1 or Machining.Steps.nCount > 1 - or bIsSplitFeature then + or bIsSplitFeature + or not Machining.bNeedTangentLeadInOut then Machining.sLeadInOutType = 'Perpendicular' if AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then @@ -105,23 +109,13 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset LeadOut.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset end - -- TODO conviene usare sempre EdgeToMachine.dElevation + BeamData.CUT_SIC - Machining.dRadialOffset?? tranne nei casi OppositeToolDirection + else - Machining.sLeadInOutType = GetLeadInOutType( Machining) - if Machining.sLeadInOutType == 'Perpendicular' then - LeadIn.dPerpDistance = 1 - LeadOut.dPerpDistance = 1 - else - -- TODO da rimuovere, già inserito in GetLeadInOutType - if abs( Machining.vtEdgeDirection:getZ()) > 0.707 then - LeadIn.dPerpDistance = 1 - LeadOut.dPerpDistance = 1 - else - LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC - LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC - end - end + Machining.sLeadInOutType = 'Tangent' + LeadIn.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC + LeadOut.dTangentDistance = TOOLS[Machining.nToolIndex].dDiameter / 2 + BeamData.CUT_SIC end + LeadIn.dElevation = 0 LeadOut.dElevation = 0 LeadIn.dCompLength = 0 @@ -165,7 +159,7 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) end --- TODO implementare SCC in funzione macchina +-- TODO da eliminare, sostituita da funzione macchina function FACEBYBLADE.GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) local nSCC = MCH_SCC.NONE @@ -286,9 +280,15 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local BladeEngagementOptionalParameters = { bIsDicing = bIsDicing } + local Engagement TIMER:startElapsed( 'GetBladeEngagement') - Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) + Cutting.bIsApplicable, Engagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) TIMER:stopElapsed( 'GetBladeEngagement') + if Cutting.bIsApplicable then + Cutting.sBladeEngagement = Engagement.sBladeEngagement + Cutting.bMoveAfterSplit = Engagement.bMoveAfterSplit + Cutting.bNeedTangentLeadInOut = Engagement.bNeedTangentLeadInOut + end -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else @@ -303,8 +303,11 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex - Cutting.sBladeEngagement = ToolInfo.sBladeEngagement - Cutting.bMoveAfterSplit = ToolInfo.bMoveAfterSplit + if Cutting.nToolIndex then + Cutting.sBladeEngagement = ToolInfo.Engagement.sBladeEngagement + Cutting.bMoveAfterSplit = ToolInfo.Engagement.bMoveAfterSplit + Cutting.bNeedTangentLeadInOut = ToolInfo.Engagement.bNeedTangentLeadInOut + end -- se non trovato utensile, la lavorazione non è applicabile if not Cutting.nToolIndex then @@ -380,7 +383,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar bIsDicing = bIsDicing } TIMER:startElapsed( 'GetBladeEngagement') - local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) + local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) TIMER:stopElapsed( 'GetBladeEngagement') -- taglio opposto non fattibile @@ -407,8 +410,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza -- il BladeEngagement non deve cambiare, altrimenti è inutile invertire la direzione - if ( sBladeEngagementOpposite == Cutting.sBladeEngagement) - and ( bMoveAfterSplit == Cutting.bMoveAfterSplit) + if ( EngagementOpposite.sBladeEngagement == Cutting.sBladeEngagement) + and ( EngagementOpposite.bMoveAfterSplit == Cutting.bMoveAfterSplit) + and ( EngagementOpposite.bNeedTangentLeadInOut == Cutting.bNeedTangentLeadInOut) and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then @@ -487,11 +491,12 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar bIsDicing = bIsDicing } TIMER:startElapsed( 'GetBladeEngagement') - local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters ) + local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters ) TIMER:stopElapsed( 'GetBladeEngagement') -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce - if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)) then + if not ( bIsApplicable and ( CurrentEngagement.sBladeEngagement == Cutting.sBladeEngagement) and ( CurrentEngagement.bMoveAfterSplit == Cutting.bMoveAfterSplit) + and ( CurrentEngagement.bNeedTangentLeadInOut == Cutting.bNeedTangentLeadInOut)) then Cutting.sEdgeUsage = 'Standard' dDepthToMachine = Cutting.dDepthToMachine end