From 4a9db5d986a64ad475271e407413fb2d5def2de0 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 4 Jul 2025 16:20:45 +0200 Subject: [PATCH] - in BLADETOWASTE e FACEBYBLADE implementato taglio ridotto e a ghigliottina, solo per facce rettangolari - in FaceData introdotta funzione IsFaceRectangular - in STR0005 aggiunto il parametro bReduceBladePath (gestito in BLADETOWASTE) --- LuaLibs/FaceData.lua | 18 ++++++ LuaLibs/MachiningLib.lua | 1 - Strategies/Standard/STR0005/STR0005.json | 10 +++ StrategyLibs/BLADETOWASTE.lua | 38 ++++++++++- StrategyLibs/FACEBYBLADE.lua | 80 +++++++++++++++++++++--- StrategyLibs/FACEBYMILL.lua | 1 + 6 files changed, 137 insertions(+), 11 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index c5ce49c..bf2a6e8 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -201,6 +201,24 @@ function FaceData.GetFacesInfo( Proc, Part) return Faces end +------------------------------------------------------------------------------------------------------------- +function FaceData.IsFaceRectangular( Proc, idFace) + local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart) + local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId) + if nContourCnt > 1 then + error( 'IsFaceRectangular : too many loops') + end + + local bIsRectangular = EgtCurveIsARectangle( nContourId) + + -- elimino curve create + for i = 1, nContourCnt do + EgtErase( nContourId + i - 1) + end + + return bIsRectangular +end + ------------------------------------------------------------------------------------------------------------- local function CompareEdgesBottomFace( EdgeA, EdgeB) -- prima i lati con facce adiacenti diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index c564fa1..b962fd6 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -414,7 +414,6 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche --- TODO da fare function MachiningLib.FindDrill( Proc, ToolSearchParameters) local ToolInfo = {} local nBestToolIndex diff --git a/Strategies/Standard/STR0005/STR0005.json b/Strategies/Standard/STR0005/STR0005.json index 996643e..62c6cab 100644 --- a/Strategies/Standard/STR0005/STR0005.json +++ b/Strategies/Standard/STR0005/STR0005.json @@ -100,6 +100,16 @@ "sMessageId": " ", "sMinUserLevel": "1" }, + { + "sName": "bReduceBladePath", + "sNameNge": "REDUCE_BLADE_PATH", + "sValue": "true", + "sDescriptionShort": "Use entire blade diameter to shorten path", + "sDescriptionLong": "", + "sType": "b", + "sMessageId": " ", + "sMinUserLevel": "1" + }, { "sName": "dStripWidth", "sNameNge": "STRIP_WIDTH", diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 039ac2d..a7cad17 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -107,7 +107,8 @@ local function GetEdgeToMachine( Edges, vtNFace, sBladeType) table.insert( EdgesSorted, Edges[i]) end - if sBladeType == 'Top' then + -- TODO separare Top e TopGuillotine; il Top deve tagliare dal basso all'alto e non scegliere il lato sotto + if ( sBladeType == 'Top') or ( sBladeType == 'TopGuillotine') then table.sort( EdgesSorted, CompareEdgesTopHead) EdgeToMachine = EdgesSorted[1] elseif sBladeType == 'Bottom' then @@ -256,9 +257,11 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) local EdgeToMachineTopBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Top') local EdgeToMachineBottomBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Bottom') local EdgeToMachineTopBladeDownUp = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'TopDownUp') + local EdgeToMachineTopBladeGuillotine = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'TopGuillotine') -- scelta lama da sopra o da sotto if nToolIndex then + -- TODO se la lama arriva da fuori chi sceglie il lato????? Sarà da scegliere in base alla testa lama nToolIndex = OptionalParameters.nToolIndex else local OptionalParametersGetBestBlade = { dElevationTop = EdgeToMachineTopBlade.dElevation + BeamData.CUT_EXTRA, @@ -266,6 +269,30 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) dElevationTopDownUp = EdgeToMachineTopBladeDownUp.dElevation + BeamData.CUT_EXTRA } nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Proc.Faces[1], OptionalParametersGetBestBlade) + + -- se possibile taglio a ghigliottina, si sceglie il lato adeguato + if sChosenBladeType == 'Top' + and OptionalParameters.bReduceBladePath + and FaceData.IsFaceRectangular( Proc, Proc.Faces[1].id) then + + -- ricerca lama migliore testa sopra + local ToolSearchParameters = {} + ToolSearchParameters.vtN = Proc.Faces[1].vtN + ToolSearchParameters.bAllowTopHead = true + ToolSearchParameters.bAllowBottomHead = false + ToolSearchParameters.bForceLongcutBlade = false + ToolSearchParameters.dElevation = nil + ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) + + if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then + local dRadialOffset = FaceByBlade.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachineTopBladeGuillotine.dLength) + if ( TOOLS[ToolInfo.nToolIndex].dMaxMaterial - EdgeToMachineTopBladeGuillotine.dElevation - BeamData.CUT_SIC) > dRadialOffset + 10 * GEO.EPS_SMALL then + nToolIndex = ToolInfo.nToolIndex + sChosenBladeType = 'TopGuillotine' + end + end + + end end -- utensile non trovato @@ -281,6 +308,8 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) EdgeToMachine = EdgeToMachineBottomBlade elseif sChosenBladeType == 'TopDownUp' then EdgeToMachine = EdgeToMachineTopBladeDownUp + elseif sChosenBladeType == 'TopGuillotine' then + EdgeToMachine = EdgeToMachineTopBladeGuillotine end dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA @@ -288,7 +317,11 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- TODO qui gestire il caso in cui si può tagliare da due lati (inizialmente solo se vtN:Y è ~= 0?). Andranno ricercati gli utensili di nuovo con l'elevazione a metà?? if dResidualDepth < 10 * GEO.EPS_SMALL then - local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = dExtendAfterTail} + local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, + nToolIndex = nToolIndex, + dExtendAfterTail = dExtendAfterTail, + bReduceBladePath = OptionalParameters.bReduceBladePath + } Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) end @@ -606,6 +639,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local b3BoxEdge = BBox3d( ptEdge1, ptEdge2) local dEdgeLengthOnX = b3BoxEdge:getDimX() if FeatureLib.IsMachiningLong( dEdgeLengthOnX, Part) then + -- TODO qui meglio return nil? è una funzione di libreria error( 'BLADETOWASTE : common edge too long') end end diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 7a43b9e..2b968f1 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -6,6 +6,7 @@ local BeamLib = require( 'BeamLib') local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') +local FaceData = require( 'FaceData') -- Tabella per definizione modulo local FACEBYBLADE = {} @@ -60,8 +61,16 @@ end local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) -- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom) - -- si determina l'eventuale riduzione da applicare in caso di inizio o fine chiusi - local dAddLengthToReduce = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine) + -- accorciamento per lati chiusi (è sempre l'impronta utensile) + local dToolMarkLength = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine) + -- allungamento per faccia singola (aperta in tutte le direzioni) + local dAddedLengthOpenFace = BeamData.CUT_EXTRA + if Machining.sCutType == 'Guillotine' then + local dGuillotineLengthToMachine + dAddedLengthOpenFace = ( - EdgeToMachine.dLength + dGuillotineLengthToMachine) / 2 + elseif Machining.sCutType == 'Reduced' then + dAddedLengthOpenFace = - FACEBYBLADE.GetPathReductionLength( Machining.nToolIndex, Machining.dMaxRadialOffset) + end if Machining.bInvert then Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed @@ -113,19 +122,19 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, bIsSplitFeature) LeadIn.dCompLength = 0 LeadOut.dCompLength = 0 if Machining.bIsStartClosed and Machining.bIsEndClosed then - LeadIn.dStartAddLength = -dAddLengthToReduce - LeadOut.dEndAddLength = -dAddLengthToReduce + LeadIn.dStartAddLength = -dToolMarkLength + LeadOut.dEndAddLength = -dToolMarkLength elseif Machining.bIsStartClosed then - LeadIn.dStartAddLength = -dAddLengthToReduce + LeadIn.dStartAddLength = -dToolMarkLength -- eventuale correzione per accorciamento maggiore di larghezza tasca LeadOut.dEndAddLength = max( -LeadIn.dStartAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA) elseif Machining.bIsEndClosed then - LeadOut.dEndAddLength = -dAddLengthToReduce + LeadOut.dEndAddLength = -dToolMarkLength -- eventuale correzione per accorciamento maggiore di larghezza tasca LeadIn.dStartAddLength = max( -LeadOut.dEndAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA) else - LeadIn.dStartAddLength = BeamData.CUT_EXTRA - LeadOut.dEndAddLength = BeamData.CUT_EXTRA + LeadIn.dStartAddLength = dAddedLengthOpenFace + LeadOut.dEndAddLength = dAddedLengthOpenFace end -- stima lunghezza reale attacchi per calcolo lunghezza lavorata local dEstimatedLeadInPerpDistance = 0 @@ -175,6 +184,42 @@ local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) end +-- dato un certo offset radiale (uscente) e la distanza da mantenere dallo spigolo, calcola di quanto la lama deve arretrare lateralmente rispetto al centro per lavorare il lato +function FACEBYBLADE.GetPathReductionLength( nToolIndex, dRadialOffset, OptionalParameters) + local Tool = TOOLS[nToolIndex] + local dToolRadius = Tool.dDiameter / 2 + + -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end + local dExtra = OptionalParameters.dExtra or BeamData.CUT_EXTRA + + -- calcolo + local dReductionLength = sqrt( ( dToolRadius - dExtra)^2 - ( dToolRadius - dRadialOffset)^2) + + return dReductionLength +end + + +-- data la lunghezza del lato da lavorare e la distanza da mantenere dallo spigolo, calcola di quanto la lama deve andare oltre per lavorare il lato +function FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, dEdgeLength, OptionalParameters) + local Tool = TOOLS[nToolIndex] + local dToolRadius = Tool.dDiameter / 2 + + -- parametri opzionali + if not OptionalParameters then + OptionalParameters = {} + end + local dExtra = OptionalParameters.dExtra or BeamData.CUT_EXTRA + + -- calcolo + local dRadialOffset = sqrt( ( dToolRadius - dExtra)^2 - ( dEdgeLength / 2)^2) + + return dRadialOffset +end + + -- TODO EdgeToMachineAlternative da gestire -- TODO invert avanzato (direzione, Z, alternativa, ...) da gestire -- TODO bilinea da gestire @@ -200,6 +245,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar local dDepthToMachine = OptionalParameters.dDepthToMachine or EdgeToMachine.dElevation local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false local bOppositeToolDirection = OptionalParameters.bOppositeToolDirection or false + local bReduceBladePath = OptionalParameters.bReduceBladePath or false local sDepth = OptionalParameters.sDepth or 0 local nToolIndex = OptionalParameters.nToolIndex local dLongitudinalOffset = OptionalParameters.dLongitudinalOffset or 0 @@ -325,6 +371,24 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar else Cutting.dDepthToMachine = dDepthToMachine Cutting.dResidualDepth = 0 + Cutting.sCutType = 'Standard' + if bReduceBladePath + and ( Proc.nFct == 1) + and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then + + local bIsTopBlade = TOOLS[nToolIndex].SetupInfo.HeadType.bTop + Cutting.dMaxRadialOffset = TOOLS[nToolIndex].dMaxMaterial - EdgeToMachine.dElevation - BeamData.CUT_SIC + Cutting.dRadialOffsetGuillotine = FACEBYBLADE.GetRadialOffsetForGuillotine( nToolIndex, EdgeToMachine.dLength) + -- taglio a ghigliottina + if bIsTopBlade and ( Cutting.dRadialOffsetGuillotine > 10 * GEO.EPS_SMALL) then + dDepthToMachine = EdgeToMachine.dElevation + Cutting.dRadialOffsetGuillotine + Cutting.sCutType = 'Guillotine' + -- taglio ridotto + elseif Cutting.dMaxRadialOffset > 10 * GEO.EPS_SMALL then + dDepthToMachine = EdgeToMachine.dElevation + Cutting.dMaxRadialOffset + Cutting.sCutType = 'Reduced' + end + end if bOppositeToolDirection then Cutting.dRadialOffset = -dDepthToMachine else diff --git a/StrategyLibs/FACEBYMILL.lua b/StrategyLibs/FACEBYMILL.lua index b7a32a7..2c8f8cc 100644 --- a/StrategyLibs/FACEBYMILL.lua +++ b/StrategyLibs/FACEBYMILL.lua @@ -78,6 +78,7 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, Part) LeadOut.dPerpDistance = 0 LeadIn.dTangentDistance = 0 LeadOut.dTangentDistance = 0 + -- TODO qui se bIsSplitFeature si deve forzare attacco perpendicolare come in FACEBYBLADE if Machining.bIsStartClosed or Machining.bIsEndClosed or Machining.CloneStepsRadial.nCount > 1 then