From ecd2147e83c0ce2de3ab2801d5dda0b295ac4bfd Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 30 Oct 2025 13:20:15 +0100 Subject: [PATCH] - in FACEBYBLADE modifiche e refactoring per contemplare nuova gestione DownUp --- LuaLibs/FaceData.lua | 41 +++++---- Strategies/Standard/STR0003/STR0003.lua | 4 +- StrategyLibs/FACEBYBLADE.lua | 117 ++++++++++++++---------- 3 files changed, 90 insertions(+), 72 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index ec7ab22..8c8a120 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -218,12 +218,7 @@ end ------------------------------------------------------------------------------------------------------------- function FaceData.IsFaceRectangular( Face) -- recupero gruppo per geometrie temporanee - local bIsTempGroupToDelete = false local idTempGroup = BeamLib.GetTempGroup() - if not idTempGroup then - idTempGroup = BeamLib.CreateTempGroup() - bIsTempGroupToDelete = true - end local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then @@ -232,23 +227,13 @@ function FaceData.IsFaceRectangular( Face) local bIsRectangular = EgtCurveIsARectangle( nContourId) - -- se necessario, elimino il gruppo temporaneo - if bIsTempGroupToDelete then - EgtErase( idTempGroup) - end - return bIsRectangular end ------------------------------------------------------------------------------------------------------------- function FaceData.IsFaceRhomboid( Face) -- recupero gruppo per geometrie temporanee - local bIsTempGroupToDelete = false local idTempGroup = BeamLib.GetTempGroup() - if not idTempGroup then - idTempGroup = BeamLib.CreateTempGroup() - bIsTempGroupToDelete = true - end local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then @@ -265,14 +250,30 @@ function FaceData.IsFaceRhomboid( Face) bIsRhomboid = true end - -- se necessario, elimino il gruppo temporaneo - if bIsTempGroupToDelete then - EgtErase( idTempGroup) - end - return bIsRhomboid end +------------------------------------------------------------------------------------------------------------- +-- calcola l'elevazione di un lato rispetto al box passato +function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) + -- recupero gruppo per geometrie temporanee + local idTempGroup = BeamLib.GetTempGroup() + + -- costruzione trimesh rettangolare centrata sul lato + -- TODO sostituire EgtSurfTmFacetOppositeSide con punti direttamente in Edge + local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + local vtEdge = ptEdge2 - ptEdge1 + local vtMove = ( Edge.vtN ^ vtEdge) + local ptRectangleVertex1 = ptEdge1 + vtMove * 100 * GEO.EPS_SMALL + local ptRectangleVertex2 = ptEdge2 + vtMove * 100 * GEO.EPS_SMALL + local ptRectangleVertex3 = ptEdge1 - vtMove * 100 * GEO.EPS_SMALL + local idEdgeTrimesh = EgtSurfTmRectangle( idTempGroup, ptRectangleVertex1, ptRectangleVertex2, ptRectangleVertex3, GDB_RT.GLOB) + + local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Raw, true, GDB_ID.ROOT) + + return dElevation +end + ------------------------------------------------------------------------------------------------------------- local function CompareEdgesBottomFace( EdgeA, EdgeB) -- prima i lati con facce adiacenti diff --git a/Strategies/Standard/STR0003/STR0003.lua b/Strategies/Standard/STR0003/STR0003.lua index 7a6afd9..95058d0 100644 --- a/Strategies/Standard/STR0003/STR0003.lua +++ b/Strategies/Standard/STR0003/STR0003.lua @@ -236,6 +236,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) local BottomEdge = LongFace.MainEdges.BottomEdge -- TODO funzione separata + -- TODO è meglio cercare la lama qui e passarla alla FACEBYBLADE, la scelta è più precisa -- lama - calcolo lavorazioni local Cutting = {} -- parametri comuni a tutte le lavorazioni cutting @@ -243,8 +244,7 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters) bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail, dPocketHeight = dPocketHeight, - bIsSplitFeature = bIsSplitFeature, - dMinNzDownUp = 0 + bIsSplitFeature = bIsSplitFeature } -- primo lato del tunnel o lato di fondo diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 1e98c73..1fefe73 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -203,12 +203,6 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end --- TODO da fare -local function GetCorrectedElevationDownUp( Face, Edge, b3Raw ) - -end - - local function IsOrientationOkForDownUp( Face, Edge, b3Raw) -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp @@ -292,14 +286,14 @@ end -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) e l'elevazione corretta (in DownUp può cambiare) function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) local sBladeEngagement = 'Standard' - local dCorrectedElevation = Edge.dElevation + local dDownUpElevation = Edge.dElevation -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - return true, sBladeEngagement, dCorrectedElevation + return true, sBladeEngagement end -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile @@ -319,9 +313,9 @@ function FACEBYBLADE.GetBladeEngagement( Face, Edge, b3Raw, Tool) if IsOrientationOkForDownUp( Face, Edge, b3Raw) then sBladeEngagement = 'DownUp' - dCorrectedElevation = GetCorrectedElevationDownUp() + dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) - return true, sBladeEngagement, dCorrectedElevation + return true, sBladeEngagement, dDownUpElevation end return false @@ -412,47 +406,40 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN -- TODO conviene spostare questi calcoli nel FaceData? Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) - -- TODO gestire lama da sotto - -- se si conosce il limite downUp (utensile forzato o downUp forzato) si decide se invertire (ToolInvert) - -- TODO esiste un limite downUp massimo per la lama da sopra?? - if nToolIndex and not dMinNzDownUp then - dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[nToolIndex]) - end - if dMinNzDownUp and FaceToMachine.vtN:getZ() < dMinNzDownUp then - Cutting.bToolInvert = true - else - Cutting.bToolInvert = false - end -- ricerca utensile if nToolIndex then Cutting.nToolIndex = nToolIndex - -- TODO qui ricevere anche la dMaxElevation o simile? decidere cosa fare se non arriva: si dovrà modificare la dResidualDepth - Cutting.sBladeEngagement = FACEBYBLADE.GetBladeEngagement( FaceToMachine, Cutting.vtToolDirection, Part.b3Raw, TOOLS[nToolIndex]) + local dDownUpElevation = dDepthToMachine + + -- si determina se il taglio è fattibile e il modo di lavorare della lama + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) + + -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile + if not Cutting.bIsApplicable + or ( Cutting.sBladeEngagement == 'DownUp' + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then + + Cutting.sMessage = 'Orientation not reachable' + EgtOutLog( Cutting.sMessage) + return Cutting, EdgeToMachine.dElevation + end + + -- si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else local ToolSearchParameters = {} ToolSearchParameters.dElevation = dDepthToMachine - if Cutting.bToolInvert then - ToolSearchParameters.vtN = -FaceToMachine.vtN - else - ToolSearchParameters.vtN = FaceToMachine.vtN - end ToolSearchParameters.bAllowTopHead = true - -- TODO bisognerà implementare anche la lama da sotto - ToolSearchParameters.bAllowBottomHead = false + ToolSearchParameters.bAllowBottomHead = true ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade - -- TODO ToolSearchParameters da rivedere per il passaggio di FaceToMachine e EdgeToMachine + ToolSearchParameters.FaceToMachine = FaceToMachine + ToolSearchParameters.EdgeToMachine = EdgeToMachine + local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) - -- ora che l'utensile è scelto, se non era definito l'angolo di DownUp lo verifico per decidere se invertire - if ToolInfo.nToolIndex and not dMinNzDownUp then - dMinNzDownUp = TOOLS[ToolInfo.nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, Cutting.vtToolDirection, TOOLS[ToolInfo.nToolIndex]) - if FaceToMachine.vtN:getZ() < dMinNzDownUp then - Cutting.bToolInvert = true - end - end Cutting.nToolIndex = ToolInfo.nToolIndex + Cutting.sBladeEngagement = ToolInfo.sBladeEngagement end - if not TOOLS[Cutting.nToolIndex] or not TOOLS[Cutting.nToolIndex].sName then + if not TOOLS[Cutting.nToolIndex] then Cutting.sMessage = 'Blade not found' Cutting.bIsApplicable = false EgtOutLog( Cutting.sMessage) @@ -478,11 +465,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- parametri della lavorazione + -- profondità (parametro DEPTH) Cutting.sDepth = sDepth + -- inizio e fine aperti o chiusi Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen + -- lato di lavoro e inversione per avere taglio concorde if TOOLS[Cutting.nToolIndex].bIsCCW then Cutting.nWorkside = MCH_MILL_WS.RIGHT @@ -491,21 +481,33 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.nWorkside = MCH_MILL_WS.LEFT Cutting.bInvert = false end - -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva per garantire taglio concorde e verso l'alto (massima qualità) + + -- se OppositeToolDirectionMode è Optimized, se possibile e necessario, si attiva la lavorazione dal lato opposto per garantire taglio concorde e verso l'alto (massima qualità) if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceRhomboid( FaceToMachine)) then + OppositeToolDirectionMode = 'Disabled' - -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza. + + -- la direzione di percorrenza del lato deve essere verso l'alto; bInvert va considerata perchè inverte la direzione di percorrenza if ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) or ( ( not Cutting.bInvert) and Cutting.vtEdgeDirection:getZ() < -100 * GEO.EPS_SMALL) then - -- si attiva OppositeToolDirection solo se non cambiano le condizioni di taglio downUp - local dNewMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, FaceToMachine.vtN, -Cutting.vtToolDirection, TOOLS[nToolIndex]) - if ( FaceToMachine.vtN:getZ() < dMinNzDownUp) == ( FaceToMachine.vtN:getZ() < dNewMinNzDownUp) then - OppositeToolDirectionMode = 'Enabled' - Cutting.vtToolDirection = -EdgeToMachine.vtN - Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) - Cutting.bInvert = not Cutting.bInvert - -- se le condizioni downUp cambiano, si setta per tagliare verso l'alto + -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta + local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = FACEBYBLADE.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) + + if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then + + if sBladeEngagementOpposite ~= 'DownUp' + or ( ( dDownUpElevationOpposite - ( EdgeToMachine.dElevation - dDepthToMachine)) > TOOLS[nToolIndex].dMaxMaterial - 10 * GEO.EPS_SMALL) then + + OppositeToolDirectionMode = 'Enabled' + Cutting.sBladeEngagement = sBladeEngagementOpposite + Cutting.vtToolDirection = -EdgeToMachine.vtN + Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -Cutting.vtToolDirection, GDB_ID.ROOT) + Cutting.bInvert = not Cutting.bInvert + end + + -- se non possibile taglio opposto, si setta per tagliare verso l'alto else if Cutting.nWorkside == MCH_MILL_WS.RIGHT then Cutting.nWorkside = MCH_MILL_WS.LEFT @@ -516,12 +518,17 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end end end + elseif OppositeToolDirectionMode == 'Enabled' then Cutting.bInvert = not Cutting.bInvert end - if Cutting.bToolInvert then + + -- ToolInvert + if Cutting.sBladeEngagement == 'DownUp' then + Cutting.bToolInvert = true Cutting.bInvert = not Cutting.bInvert end + -- profondità da lavorare e offset radiale if OptionalParameters.dPocketHeight then if TOOLS[Cutting.nToolIndex].dMaxDepth > dDepthToMachine - 10 * GEO.EPS_SMALL then @@ -571,8 +578,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.dRadialOffset = EdgeToMachine.dElevation - dDepthToMachine end end + -- completamento Cutting.dCompletionPercentage = ( 1 - Cutting.dResidualDepth / Cutting.dDepthToMachine) * 100 + -- step verticale e offset longitudinale Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness) Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY @@ -586,10 +595,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar else Cutting.dLongitudinalOffset = dLongitudinalOffset end + -- distanza di sicurezza Cutting.dStartSafetyLength = BeamData.CUT_SIC + -- overlap Cutting.dOverlap = 0 + -- EdgeUse e frame lavorazione if OppositeToolDirectionMode == 'Enabled' then Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -Cutting.vtToolDirection) @@ -600,10 +612,13 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar --Cutting.vtFaceUse = Cutting.vtToolDirection Cutting.nEdgesFaceUse = EdgeToMachine.id end + -- SCC Cutting.nSCC = GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN) + -- asse bloccato Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX())) + -- eventuale step orizzontale Cutting.CloneStepsRadial = {} if not dRadialStepSpan then @@ -615,8 +630,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.CloneStepsRadial.nCount = 1 Cutting.CloneStepsRadial.dStep = Cutting.dDepthToMachine end + -- approccio e retrazione Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine, bIsSplitFeature) + -- lunghezza lavorata -- TODO per il calcolo del dLengthOnX si deve correggere con allungamento / accorciamento percorso Cutting.dLengthToMachine = EdgeToMachine.dLength + Cutting.LeadIn.dStartAddLength + Cutting.LeadOut.dEndAddLength