From b43eca9f27b55db020d554b05eb531cbd234b5e7 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 15 Sep 2025 17:53:49 +0200 Subject: [PATCH 1/2] - in BLADETOWASTE gestito il caso di feature concave < 90deg e piccoli aggiustamenti --- Strategies/AvailableStrategyList.json | 2 +- Strategies/Standard/STR0005/STR0005.lua | 1 + StrategyLibs/BLADETOWASTE.lua | 118 +++++++++++++++++++----- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/Strategies/AvailableStrategyList.json b/Strategies/AvailableStrategyList.json index c524082..f308353 100644 --- a/Strategies/AvailableStrategyList.json +++ b/Strategies/AvailableStrategyList.json @@ -118,7 +118,7 @@ "nGrp": 0, "TopologyList" : [ { "sName": "Feature", - "StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0010"} ] + "StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ] } ] }, diff --git a/Strategies/Standard/STR0005/STR0005.lua b/Strategies/Standard/STR0005/STR0005.lua index 48726b3..35853ac 100644 --- a/Strategies/Standard/STR0005/STR0005.lua +++ b/Strategies/Standard/STR0005/STR0005.lua @@ -133,6 +133,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) if Strategy.Parameters.dMaxYAngleTopBlade then dMaxNyTopBlade = sin( Strategy.Parameters.dMaxYAngleTopBlade) end + -- TODO rimuovere dMinNzTopBlade e dMaxNyTopBlade opzionali? non sono gestiti ovunque e probabilmente hanno utilizzo limitato local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume, dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMinNzTopBlade = dMinZTopBlade, diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 6bdf18b..c45a7f5 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -265,11 +265,11 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters) -- se ho già l'utensile, devo solo discriminare se è lama sopra o sotto e verificare se ci arriva if OptionalParameters.nToolIndex then if TOOLS[OptionalParameters.nToolIndex].SetupInfo.HeadType.bTop then - if TOOLS[OptionalParameters.nToolIndex].dMaxMaterial > dElevationTop - 10 * GEO.EPS_SMALL then + if ( not dElevationTop) or ( TOOLS[OptionalParameters.nToolIndex].dMaxMaterial > dElevationTop - 10 * GEO.EPS_SMALL) then nToolIndexTop = OptionalParameters.nToolIndex end elseif TOOLS[OptionalParameters.nToolIndex].SetupInfo.HeadType.bBottom then - if TOOLS[OptionalParameters.nToolIndex].dMaxMaterial > dElevationBottom - 10 * GEO.EPS_SMALL then + if ( not dElevationBottom) or ( TOOLS[OptionalParameters.nToolIndex].dMaxMaterial > dElevationBottom - 10 * GEO.EPS_SMALL) then nToolIndexBottom = OptionalParameters.nToolIndex end end @@ -365,21 +365,22 @@ end local function GetSingleCutStrategy( Proc, Part, OptionalParameters) - local FaceToMachine = Proc.Faces[1] - local sChosenBladeType - - -- lati da lavorare in base al tipo di lama - local EdgeToMachineList = { - Top = GetEdgeToMachine(FaceToMachine.Edges, FaceToMachine.vtN, 'Top'), - Bottom = GetEdgeToMachine(FaceToMachine.Edges, FaceToMachine.vtN, 'Bottom'), - TopDownUp = GetEdgeToMachine(FaceToMachine.Edges, FaceToMachine.vtN, 'TopDownUp'), - TopGuillotine = GetEdgeToMachine(FaceToMachine.Edges, FaceToMachine.vtN, 'TopGuillotine') - } - -- parametri opzionali OptionalParameters = OptionalParameters or {} local nToolIndex = OptionalParameters.nToolIndex - local bReduceBladePath = OptionalParameters.bReduceBladePath + local bReduceBladePath = OptionalParameters.bReduceBladePath or false + local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1] + -- lati da lavorare in base al tipo di lama + -- se non arrivano dall'esterno si cercano i migliori disponibili + local EdgeToMachineList = OptionalParameters.EdgeToMachineList + or { + Top = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Top'), + Bottom = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'Bottom'), + TopDownUp = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopDownUp'), + TopGuillotine = GetEdgeToMachine( FaceToMachine.Edges, FaceToMachine.vtN, 'TopGuillotine') + } + + local sChosenBladeType -- se nToolIndex è presente, GetBestBlade sceglierà solo il lato, altrimenti sceglierà lama e lato local OptionalParametersGetBestBlade = { @@ -394,7 +395,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters) if sChosenBladeType == 'Top' and bReduceBladePath and FaceData.IsFaceRectangular( Proc, FaceToMachine.id) then -- ricerca lama migliore testa sopra local ToolInfo = MachiningLib.FindBlade( Proc, { - vtN = Proc.Faces[1].vtN, + vtN = FaceToMachine.vtN, bAllowTopHead = true, bAllowBottomHead = false }) @@ -416,11 +417,10 @@ end local function GetDualSideCutStrategy( Proc, OptionalParameters) - local FaceToMachine = Proc.Faces[1] - -- parametri opzionali OptionalParameters = OptionalParameters or {} local nToolIndex = OptionalParameters.nToolIndex + local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1] local CuttingParametersList local EdgeToMachine @@ -708,9 +708,10 @@ local function CutWithDicing( Proc, Part, OptionalParameters) OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) - -- se nessun cubetto trovato, si richiama il taglio singolo + -- se nessun cubetto trovato, si richiama ricorsivamente la BladeToWaste forzando di non fare i cubetti if #vCuts == 0 then - Machinings, Result = CutWholeWaste( Proc, Part, OptionalParameters) + OptionalParameters.bDisableDicing = true + Machinings, Result = BLADETOWASTE.Make( Proc, Part, OptionalParameters) return Machinings, Result end @@ -976,6 +977,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) OptionalParameters = OptionalParameters or {} local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0 local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0 + local bDisableDicing = OptionalParameters.bDisableDicing or false local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries if bSaveAddedGeometries == nil then bSaveAddedGeometries = true @@ -994,6 +996,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) -- calcolo lavorazioni if Proc.nFct == 1 then + Machinings, Result = MakeOneFace( Proc, Part, OptionalParameters) elseif Proc.nFct == 2 then @@ -1055,15 +1058,82 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) Result = FeatureLib.GetStrategyResultNotApplicable() end - -- feature concava >= 90deg: lavorata con cubetti - elseif dAngleBetweenFaces >= -91 then + -- feature concava >= 90deg: lavorata con cubetti, se attivi + elseif ( not bDisableDicing) and ( dAngleBetweenFaces >= -91) then Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters) - -- feature concava < 90deg: lavorata come 2 facce singole con accorciamento + -- qui arrivano feature concave < 90deg, oppure >= 90deg con cubetti disabilitati: lavorata come 2 facce singole con accorciamento else - -- TODO da fare + -- per ogni faccia si calcola la lavorazione + for i = 1, #Proc.Faces do + -- ricerca lato in comune da lavorare + local nCommonEdgeIndex + for j = 1, #Proc.Faces[i].Edges do + if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then + nCommonEdgeIndex = j + end + end + local EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex] + + -- scelta lama + local nToolIndex = OptionalParameters.nToolIndex + if not nToolIndex then + local OptionalParametersGetSingleCutStrategy = { + bReduceBladePath = false, + nFaceToMachineIndex = i, + EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine, TopDownUp = EdgeToMachine} + } + nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) + end + + -- se lama non trovata si esce dal ciclo e risulterà incompleta o non applicabile + if not nToolIndex then + break + end + + -- calcolo accorciamento + local dPathShortening = max( 0, TOOLS[nToolIndex].dThickness / tan( 180 + dAngleBetweenFaces)) + + -- lavorazione faccia + local OptionalParametersFaceByBlade = { + dDepthToMachine = EdgeToMachine.dElevation - dPathShortening, + nToolIndex = nToolIndex, + dExtendAfterTail = OptionalParameters.dExtendAfterTail, + bReduceBladePath = false + } + local Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[i], EdgeToMachine, OptionalParametersFaceByBlade) + + -- aggiunta lavorazione + if Cutting and Cutting.bIsApplicable then + table.insert( Machinings, Cutting) + end + end + + -- calcolo risultati + if #Machinings > 0 then + local dCompletionPercentage = 0 + + if #Machinings == 2 + and Machinings[1].dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL + and Machinings[2].dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then + + Result.sStatus = 'Completed' + dCompletionPercentage = 100 + else + + Result.sStatus = 'Not-Completed' + dCompletionPercentage = ( ( ( Machinings[1] and Machinings[1].dCompletionPercentage) or 0) + ( ( Machinings[2] and Machinings[2].dCompletionPercentage) or 0)) / 2 + end + + Result.dCompletionPercentage = dCompletionPercentage + Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage) + Result.nQuality = FeatureLib.GetStrategyQuality( Machinings) + Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) + Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) + else + Result = FeatureLib.GetStrategyResultNotApplicable() + end end - end return Machinings, Result From edeb99bdb9f2d70afa04ea85bbe80cbb78c30905 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Tue, 16 Sep 2025 10:11:56 +0200 Subject: [PATCH 2/2] - In GetStrategyQuality rimossi stati lavorazione dettagliati, si utilizzano quelli aggregati. - Adeguate strategia che utilizzavano i dati dettagliati --- LuaLibs/FeatureLib.lua | 20 +++++++------------- Strategies/Standard/STR0007/STR0007.lua | 13 +++++++++++-- Strategies/Standard/STR0011/STR0011.lua | 24 +++++++++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 10ea6ae..3768975 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -594,16 +594,19 @@ function FeatureLib.GetStrategyQuality( Parameter) elseif type( Parameter) == "string" then local sMachiningTag = Parameter -- #### STATI DI LAVORAZIONE AGGREGATI #### -- - -- FINE = lavorazione eccellente, non dovrebbero esscerci scheggiature - if sMachiningTag == 'FINE' then + -- BEST = lavorazione eccellente, la migliore qualità che si possa ottenere + if sMachiningTag == 'BEST' then nQuality = 5 + -- FINE = lavorazione ottima, non dovrebbero esscerci scheggiature + elseif sMachiningTag == 'FINE' then + nQuality = 4 -- STD = lavorazione accettabile, potrebbe avere scheggiature minime elseif sMachiningTag == 'STD' then nQuality = 3 - -- SEMI = lavorato accettabile, la lavorazione potrebbe avere scheggiature minime, mancano piccoli dettagli alla lavorazione + -- SEMI = lavorazione accettabile, potrebbe avere scheggiature minime, mancano piccoli dettagli alla lavorazione (es. se vengono lasciati i raggi fresa sugli spigoli) elseif sMachiningTag == 'SEMI' then nQuality = 2.5 - -- ROUGH = + -- ROUGH = Lavorazione scadente, scheggiatura molto probabile, potrebbe non essere precisa elseif sMachiningTag == 'ROUGH' then nQuality = 1 -- #### UTENSILI DI LAVORAZIONE UTILIZZATI #### -- @@ -615,15 +618,6 @@ function FeatureLib.GetStrategyQuality( Parameter) nQuality = 3 elseif sMachiningTag == 'MORTISE' then nQuality = 1 - -- #### STATI DI LAVORAZIONE DETTAGLIATI #### -- - elseif sMachiningTag == 'DrillBothSide' or sMachiningTag == 'DrillBlind' then - nQuality = 5 - elseif sMachiningTag == 'MillPlusBladeAS' then - nQuality = 4.5 - elseif sMachiningTag == 'ChainPlusBladeAS' or sMachiningTag == 'MillPlusMillAS' then - nQuality = 4 - elseif sMachiningTag == 'DrillOneSide' then - nQuality = 3 else nQuality = 0 end diff --git a/Strategies/Standard/STR0007/STR0007.lua b/Strategies/Standard/STR0007/STR0007.lua index de01aa8..ad8d50e 100644 --- a/Strategies/Standard/STR0007/STR0007.lua +++ b/Strategies/Standard/STR0007/STR0007.lua @@ -160,7 +160,15 @@ function GetMortiseMachiningResult( Proc, Result) TotalResult.sStatus = Result.Milling.sStatus TotalResult.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) TotalResult.dMRR = ( Result.Milling.dMRR + Result.Cutting.dMRR) / 2 - TotalResult.nQuality = FeatureLib.GetStrategyQuality( EgtIf( Strategy.Machining.bCuttingWithMill, 'STD', 'FINE')) + local sQuality + if not Strategy.Machining.bCuttingWithMill and Strategy.Machining.bAntiSplint then + sQuality = 'BEST' + elseif Strategy.Machining.bAntiSplint then + sQuality = 'FINE' + else + sQuality = 'STD' + end + TotalResult.nQuality = FeatureLib.GetStrategyQuality( sQuality) TotalResult.nFeatureRotationIndex = GetFeatureRotationIndex( Proc) TotalResult.sInfo = '' -- lavorazione mortasa completa @@ -168,7 +176,8 @@ function GetMortiseMachiningResult( Proc, Result) TotalResult.sStatus = Result.Milling.sStatus TotalResult.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) TotalResult.dMRR = Result.Milling.dMRR - TotalResult.nQuality = FeatureLib.GetStrategyQuality( 'MILL') + local sQuality = EgtIf( Strategy.Parameters.bAntiSplint, 'BEST', 'STD') + TotalResult.nQuality = FeatureLib.GetStrategyQuality( sQuality) TotalResult.nFeatureRotationIndex = GetFeatureRotationIndex( Proc) TotalResult.sInfo = '' -- lavorazione incompleta diff --git a/Strategies/Standard/STR0011/STR0011.lua b/Strategies/Standard/STR0011/STR0011.lua index 6baeb6c..df14470 100644 --- a/Strategies/Standard/STR0011/STR0011.lua +++ b/Strategies/Standard/STR0011/STR0011.lua @@ -20,6 +20,7 @@ local Strategy = {} local function GetDrillingStrategy( Proc, Part) local ToolSearchParameters = {} local Machining = {} + local sQuality -- se lavorazione orizzontale if Proc.FeatureInfo.bIsDrillHorizontal then @@ -65,7 +66,12 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = 5 Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( EgtIf( bDouble, 'DrillBothSide', 'DrillOneSide')) + if bDouble or not Proc.FeatureInfo.bIsDrillOpen then + sQuality = 'FINE' + else + sQuality = 'ROUGH' + end + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( sQuality) Strategy.Result.sInfo = '' else Strategy.Result.sStatus = 'Not-Completed' @@ -74,7 +80,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( EgtIf( bDouble, 'DrillBothSide', 'DrillOneSide')) + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'FINE') -- se non completo, anche se fosse foro singolo, comunque non esce dall'altra parte, quindi non scheggia end end -- se lavorazione verticale @@ -102,7 +108,7 @@ local function GetDrillingStrategy( Proc, Part) end -- se possono lavorare entrambi e si deve fare lavorazione doppia e si riesce a completare - if Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex and + if Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex and ( Strategy.Parameters.sDrillingMode == 'FORCE_TWO' or Strategy.Parameters.sDrillingMode == 'AUTO') and Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then @@ -125,7 +131,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.nCompletionIndex = 5 Strategy.Result.sInfo = '' Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillBothSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'FINE') -- se utensile 1 esegue completamente elseif Drilling.ToolInfo.nToolIndex and Drilling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and @@ -139,7 +145,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = 5 Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillOneSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE')) Strategy.Result.sInfo = '' -- se utensile 2 esegue completamente elseif Drilling2.ToolInfo.nToolIndex and Drilling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL and @@ -154,7 +160,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.sStatus = 'Completed' Strategy.Result.nCompletionIndex = 5 Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillOneSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( EgtIf( Proc.FeatureInfo.bIsDrillOpen, 'ROUGH', 'FINE')) Strategy.Result.sInfo = '' -- se possono lavorare entrambi elseif Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex then @@ -183,7 +189,7 @@ local function GetDrillingStrategy( Proc, Part) end -- voto Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillBothSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'FINE') -- se utensile 1 non completo elseif Drilling.ToolInfo.nToolIndex and ( Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' or Proc.FeatureInfo.bIsDrillOpen) then Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth @@ -199,7 +205,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillOneSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'FINE') -- se utensile 2 non completo elseif Drilling2.ToolInfo.nToolIndex and Strategy.Parameters.sDrillingMode ~= 'FORCE_TWO' then Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth @@ -216,7 +222,7 @@ local function GetDrillingStrategy( Proc, Part) Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) Strategy.Result.sInfo = 'Drill not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) - Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'DrillOneSide') + Strategy.Result.nQuality = FeatureLib.GetStrategyQuality( 'FINE') else local sMessage -- se non sono state trovate punte