From 7b4673acef3e86cd3a5368e905323aecf161d252 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 3 Nov 2025 16:29:12 +0100 Subject: [PATCH] - varie modifiche ai tagli di lama per DownUp, caso solo 2d - in FaceData.GetEdgesInfo si scrivono anche i ptStart e ptEnd; IsFaceRhomboid diventa IsFaceParallelogram - in BeamLib aggiunta IsEdgeOnBox --- LuaLibs/BeamLib.lua | 46 ++++++++++++++++++++++++++++++++--- LuaLibs/FaceData.lua | 29 ++++++++++++---------- LuaLibs/MachiningLib.lua | 42 +++++++++++++++++++++----------- StrategyLibs/BLADETOWASTE.lua | 20 +++++++-------- StrategyLibs/FACEBYBLADE.lua | 11 +++++---- 5 files changed, 102 insertions(+), 46 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 325c13b..321fddc 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -793,13 +793,13 @@ function BeamLib.GetPlaneOrientation( vtN) -- modulo della proiezione in ogni piano local Orientation = { - { sPlane = "XY", dMagnitude = sqrt( x^2 + y^2)}, - { sPlane = "XZ", dMagnitude = sqrt( x^2 + z^2)}, - { sPlane = "YZ", dMagnitude = sqrt( y^2 + z^2)} + { sPlane = "XY", dMagnitude = EgtClamp( sqrt( x^2 + y^2), 0, 1)}, + { sPlane = "XZ", dMagnitude = EgtClamp( sqrt( x^2 + z^2), 0, 1)}, + { sPlane = "YZ", dMagnitude = EgtClamp( sqrt( y^2 + z^2), 0, 1)} } -- modulo totale in 3d - local dTotalMagnitude = sqrt( x^2 + y^2 + z^2) + local dTotalMagnitude = EgtClamp( sqrt( x^2 + y^2 + z^2), 0, 1) -- incidenza del modulo in ogni piano for i = 1, #Orientation do @@ -818,6 +818,44 @@ function BeamLib.GetPlaneOrientation( vtN) return Orientation end +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsEdgeOnBox( Face, Edge, b3Box) + -- TODO sostituire con informazioni direttamente da box e rimuuovere il parametro Face + local ptEdge1, _, ptEdge2 = EgtSurfTmFacetOppositeSide( Face.idTrimesh, Face.id, -Edge.vtN, GDB_ID.ROOT) + + -- il lato è sul box se i suoi estremi sono entrambi sullo stesso lato del box + if ptEdge1:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL + and ptEdge2:getZ() > b3Box:getMax():getZ() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL + and ptEdge2:getZ() > b3Box:getMin():getZ() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL + and ptEdge2:getY() > b3Box:getMax():getY() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL + and ptEdge2:getY() > b3Box:getMin():getY() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL + and ptEdge2:getX() > b3Box:getMax():getX() - 500 * GEO.EPS_SMALL then + + return true + end + if ptEdge1:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL + and ptEdge2:getX() > b3Box:getMin():getX() - 500 * GEO.EPS_SMALL then + + return true + end +end + ------------------------------------------------------------------------------------------------------------- -- nNearSide : 3=Z+, -3=Z- function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, dMaxDist, nNearSide) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 8c8a120..d378ea1 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -136,6 +136,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace ) end CurrentEdge.bIsStartOpen = EdgesEgt[nPreviousEdgeIndex].Open CurrentEdge.bIsEndOpen = EdgesEgt[nNextEdgeIndex].Open + CurrentEdge.ptStart = Point3d( EdgesEgt[i].Start) + CurrentEdge.ptEnd = Point3d( EdgesEgt[nNextEdgeIndex].Start) CurrentEdge.sType = 'Standard' CurrentEdge.id = i - 1 @@ -216,13 +218,13 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) end ------------------------------------------------------------------------------------------------------------- -function FaceData.IsFaceRectangular( Face) +function FaceData.IsFaceRectangle( Face) -- recupero gruppo per geometrie temporanee local idTempGroup = BeamLib.GetTempGroup() local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then - error( 'IsFaceRectangular : too many loops') + error( 'IsFaceRectangle : too many loops') end local bIsRectangular = EgtCurveIsARectangle( nContourId) @@ -231,13 +233,13 @@ function FaceData.IsFaceRectangular( Face) end ------------------------------------------------------------------------------------------------------------- -function FaceData.IsFaceRhomboid( Face) +function FaceData.IsFaceParallelogram( Face) -- recupero gruppo per geometrie temporanee local idTempGroup = BeamLib.GetTempGroup() local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Face.idTrimesh, Face.id, idTempGroup) if nContourCnt > 1 then - error( 'IsFaceRhomboid : too many loops') + error( 'IsFaceParallelogram : too many loops') end local bIsTrapezoid = EgtCurveIsATrapezoid( nContourId) @@ -255,21 +257,22 @@ end ------------------------------------------------------------------------------------------------------------- -- calcola l'elevazione di un lato rispetto al box passato -function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) +function FaceData.GetEdgeElevationInBBox( Face, Edge, b3Box ) -- 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) + -- ptMid è traslato leggermente all'interno per assicurare l'intersezione con il box + local dExtraLength = 500 * GEO.EPS_SMALL + local ptMid = ( ptEdge1 + ptEdge2) / 2 + Edge.vtN * dExtraLength + local idEdgeTrimesh - local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Raw, true, GDB_ID.ROOT) + -- piano di taglio del box orientato come la normale del lato e passante da ptMid + idEdgeTrimesh = EgtSurfTmPlaneInBBox( idTempGroup, ptMid, Edge.vtN, b3Box, GDB_RT.GLOB) + + -- al calcolo dell'elevazione devo aggiungere la lunghezza di cui avevo traslato il ptMid + local dElevation = EgtSurfTmFacetElevationInBBox( idEdgeTrimesh, 0, b3Box, true, GDB_ID.ROOT) + dExtraLength return dElevation end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 3168fe5..27fe912 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -284,13 +284,20 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end ------------------------------------------------------------------------------------------------------------- -local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) +local function IsBladeOrientationOkForDownUp( Face, Edge, b3Part) -- se l'utensile lavora perpendicolarmente, l'orientamento è sempre valido per DownUp if AreSameVectorApprox( Face.vtN, Edge.vtN) then return true end + + -- componente Z negativa di vtTool, ossia testa sotto alla trave e rischio collisione carro Z: non lavorabile in Downup + -- TODO con lama da sopra il test è per Z > 0!!! + if Edge.vtN:getZ() < - 10 * GEO.EPS_SMALL then + + return false + end -- orientamento 3d della faccia: non lavorabile in DownUp -- TODO implementare gestione DownUp in 3d @@ -327,14 +334,14 @@ local function IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) local dFaceComponent = Face.vtN["get" .. sAxis](Face.vtN) local dEdgeComponent = Edge.vtN["get" .. sAxis](Edge.vtN) local dPtonboxComponent = ptOnBox["get" .. sAxis](ptOnBox) - local dMaxb3rawComponent = b3Raw:getMax()["get" .. sAxis](b3Raw:getMax()) - local dMinb3rawComponent = b3Raw:getMin()["get" .. sAxis](b3Raw:getMin()) + local dMaxb3PartComponent = b3Part:getMax()["get" .. sAxis](b3Part:getMax()) + local dMinb3PartComponent = b3Part:getMin()["get" .. sAxis](b3Part:getMin()) if dFaceComponent * dEdgeComponent < 10 * GEO.EPS_SMALL then if dEdgeComponent > GEO.EPS_SMALL then - return dPtonboxComponent > dMaxb3rawComponent - 500 * GEO.EPS_SMALL + return dPtonboxComponent > dMaxb3PartComponent - 500 * GEO.EPS_SMALL else - return dPtonboxComponent < dMinb3rawComponent + 500 * GEO.EPS_SMALL + return dPtonboxComponent < dMinb3PartComponent + 500 * GEO.EPS_SMALL end end return false @@ -365,7 +372,7 @@ 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 MachiningLib.GetBladeEngagement( Face, Edge, b3Raw, Tool) +function MachiningLib.GetBladeEngagement( Face, Edge, b3Part, Tool, bAllowEntryFromInternalEdge) local sBladeEngagement = 'Standard' local dDownUpElevation = Edge.dElevation @@ -384,17 +391,24 @@ function MachiningLib.GetBladeEngagement( Face, Edge, b3Raw, Tool) return false end - -- faccia non rettangolare: non lavorabile in DownUp - if not FaceData.IsFaceRectangular( Face) then + -- faccia non parallelogramma: non lavorabile in DownUp + if not FaceData.IsFaceParallelogram( Face) then + + return false + end + + -- se il lato di approccio non è sul box e non è espressamente consentito (es: cubetti), non lavorabile in DownUp + local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN) + if not bAllowEntryFromInternalEdge and not BeamLib.IsEdgeOnBox( Face, EdgeOpposite, b3Part) then return false end -- orientamento faccia / utensile compatibili con DownUp: lavorabile, si calcola l'elevazione reale per DownUp e si ritorna - if IsBladeOrientationOkForDownUp( Face, Edge, b3Raw) then + if IsBladeOrientationOkForDownUp( Face, Edge, b3Part) then sBladeEngagement = 'DownUp' - dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Raw ) + dDownUpElevation = FaceData.GetEdgeElevationInBBox( Face, Edge, b3Part) return true, sBladeEngagement, dDownUpElevation end @@ -544,7 +558,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local dElevation = ToolSearchParameters.dElevation or 0 local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine - local b3Raw = ToolSearchParameters.b3Raw + local b3Part = ToolSearchParameters.b3Part local nBestToolIndex local dBestToolResidualDepth = 0 @@ -563,12 +577,12 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) -- se dati sufficienti, si determina se con questo utensile il taglio è fattibile e il modo di lavorare della lama if bIsToolCompatible then - if FaceToMachine and EdgeToMachine and dElevation then - local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Raw, TOOLS[i]) + if FaceToMachine and EdgeToMachine and dElevation and b3Part then + local bIsBladeOk, sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, b3Part, TOOLS[i]) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non compatibile if not bIsBladeOk or ( sBladeEngagement == 'DownUp' - and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then + and ( dDownUpElevation - ( EdgeToMachine.dElevation - dElevation)) > TOOLS[i].dMaxMaterial - 10 * GEO.EPS_SMALL) then bIsToolCompatible = false end diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index ce49c81..03a1432 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -280,7 +280,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationTop, FaceToMachine = Face, EdgeToMachine = EdgeToMachineTop, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexTop = ToolInfo.nToolIndex @@ -292,7 +292,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) dElevation = dElevationBottom, FaceToMachine = Face, EdgeToMachine = EdgeToMachineBottom, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then nToolIndexBottom = ToolInfo.nToolIndex @@ -381,7 +381,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, FaceToMachine, OptionalParametersGetBestBlade) -- se possibile, upgrade del taglio tipo 'Top' a taglio a ghigliottina. Si tenta anche se il taglio singolo non è riuscito. - if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangular( FaceToMachine) then + if ( sChosenBladeType == 'Top' or not nToolIndex) and bReduceBladePath and FaceData.IsFaceRectangle( FaceToMachine) then local nToolIndexGuillotine -- ricerca lama migliore testa sopra @@ -390,7 +390,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) bAllowBottomHead = false, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachineList.Top, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) nToolIndexGuillotine = ToolInfo.nToolIndex @@ -435,7 +435,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) -- ricerca lama testa sotto local ToolInfoBottomBlade = MachiningLib.FindBlade( Proc, { @@ -444,7 +444,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) local bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -462,7 +462,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineBottom, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) bIsBottomLimited = ToolInfoBottomBlade.dResidualDepth > 10 * GEO.EPS_SMALL @@ -478,7 +478,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachineTop, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) bIsTopLimited = ToolInfoTopBlade.dResidualDepth > 10 * GEO.EPS_SMALL end @@ -511,7 +511,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) dElevation = dDepthToMachine, FaceToMachine = FaceToMachine, EdgeToMachine = EdgeToMachine, - b3Raw = Part.b3Raw + b3Part = Part.b3Part }) -- se lama ci arriva si assegnano utensili e profondità da ritornare @@ -586,7 +586,7 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- se taglio da un lato non ce la fa, si prova da due lati -- TODO valutare se estendere ai non parallelogrammi - elseif FaceData.IsFaceRhomboid( Proc.Faces[1]) then + elseif FaceData.IsFaceParallelogram( Proc.Faces[1]) then local CuttingParametersList CuttingParametersList, EdgeToMachine = GetDualSideCutStrategy( Proc, Part, OptionalParameters) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 837d95e..1e2a7f5 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -260,6 +260,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' + local bAllowEntryFromInternalEdge = OptionalParameters.bAllowEntryFromInternalEdge or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -278,7 +279,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dDownUpElevation = dDepthToMachine -- si determina se il taglio è fattibile e il modo di lavorare della lama - Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex]) + Cutting.bIsApplicable, Cutting.sBladeEngagement, dDownUpElevation = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) -- orientamento non raggiungibile o elevazione eccessiva per DownUp: non applicabile if not Cutting.bIsApplicable @@ -299,7 +300,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade ToolSearchParameters.FaceToMachine = FaceToMachine ToolSearchParameters.EdgeToMachine = EdgeToMachine - ToolSearchParameters.b3Raw = Part.b3Raw + ToolSearchParameters.b3Part = Part.b3Part local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) Cutting.nToolIndex = ToolInfo.nToolIndex @@ -349,7 +350,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- 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 + if ( OppositeToolDirectionMode == 'Optimized') and ( Proc.nFct == 1) and ( FaceData.IsFaceParallelogram( FaceToMachine)) then OppositeToolDirectionMode = 'Disabled' @@ -359,7 +360,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- si attiva OppositeToolDirection solo se il taglio è fattibile anche in direzione opposta local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -Cutting.vtToolDirection) - local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex]) + local bIsApplicableOpposite, sBladeEngagementOpposite, dDownUpElevationOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part.b3Raw, TOOLS[nToolIndex], bAllowEntryFromInternalEdge) if bIsApplicableOpposite and ( sBladeEngagementOpposite == Cutting.sBladeEngagement) then @@ -421,7 +422,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.sEdgeUsage = 'Standard' if bReduceBladePath and ( Proc.nFct == 1) - and FaceData.IsFaceRectangular( FaceToMachine) then + and FaceData.IsFaceRectangle( FaceToMachine) then local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - Cutting.dDepthToMachine - BeamData.CUT_SIC