From 6832d1d95b681412eb8593ab09df96f0743a0f16 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Thu, 25 Jun 2026 17:24:56 +0200 Subject: [PATCH] =?UTF-8?q?-=20in=20BeamExec.CalculateStrategies=20se=20i?= =?UTF-8?q?=20tagli=20di=20testa=20o=20coda=20obliqui=20non=20funzionano?= =?UTF-8?q?=20si=20ripristinano=20quelli=20originali=20-=20inHEADCUT=20e?= =?UTF-8?q?=20TAILCUT,=20se=20non=20=C3=A8=20taglio=20originale,=20si=20ca?= =?UTF-8?q?lcola=20risultato=20anche=20per=20CalculateStrategies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/BeamExec.lua | 134 ++++++++++++++---------- LuaLibs/FeatureLib.lua | 2 +- Strategies/Standard/HEADCUT/HEADCUT.lua | 60 +++++++---- Strategies/Standard/TAILCUT/TAILCUT.lua | 60 +++++++---- 4 files changed, 158 insertions(+), 98 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 917a7bd..329e874 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1131,64 +1131,92 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione che processa tutte le feature del pezzo local function CalculateStrategies( vProcSingleRot, Part) - -- per ogni feature - for i = 1, #vProcSingleRot do - -- processo tutte le feature attive - local Proc = vProcSingleRot[i] - if Proc.nFlg ~= 0 then - -- controllo se ci sono strategie disponibili - if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then - -- se le strategie disponibili sono le basic, non si possono customizzare valori di default da interfaccia - -- si leggono allora eventuali parametri di default scritti come info sulla feature - if Proc.AvailableStrategies.bIsBasicStrategy then - -- si recuperano eventuali parametri custom - for j = 1, #Proc.AvailableStrategies do - -- essendo una strategia basic, la lista dei parametri custom dovrebbe essere sempre vuota. Si leggono ora - if not Proc.AvailableStrategies[j].ParameterList then - Proc.AvailableStrategies[j].ParameterList = BCS.GetParametersFromBasicCustomerStrategies( Proc, Proc.AvailableStrategies[j].sStrategyId) + local nCounter = 0 + repeat + nCounter = nCounter + 1 + local bToReprocess = false + -- per ogni feature + for i = 1, #vProcSingleRot do + -- processo tutte le feature attive + local Proc = vProcSingleRot[i] + if Proc.nFlg ~= 0 then + -- controllo se ci sono strategie disponibili + if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then + -- se le strategie disponibili sono le basic, non si possono customizzare valori di default da interfaccia + -- si leggono allora eventuali parametri di default scritti come info sulla feature + if Proc.AvailableStrategies.bIsBasicStrategy then + -- si recuperano eventuali parametri custom + for j = 1, #Proc.AvailableStrategies do + -- essendo una strategia basic, la lista dei parametri custom dovrebbe essere sempre vuota. Si leggono ora + if not Proc.AvailableStrategies[j].ParameterList then + Proc.AvailableStrategies[j].ParameterList = BCS.GetParametersFromBasicCustomerStrategies( Proc, Proc.AvailableStrategies[j].sStrategyId) + end + end + -- si riprocessano le strategie dopo che sono stati letti i parametri + Proc.AvailableStrategies = BCS.UpdateStrategies( Proc.AvailableStrategies) + end + + -- ciclo tutte le strategie della feature + for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do + -- eseguo file config con i parametri di default + local CurrentStrategy = {} + CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) + -- controllo che le librerie siano state effettivamente caricate + if CurrentStrategy.Config and CurrentStrategy.Script then + -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati + _, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy]) + + -- se taglio di testa o coda sostitutivo non applicabile si ripristina l'originale + if Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus ~= 'Completed' then + if ID.IsHeadCut( Proc) and not Proc.bIsOriginalHeadcut then + Proc.HeadProcOriginal.nFlg = 1 + Proc.HeadProcOriginal.nIndexMasterProc = nil + Proc.Topology = FeatureLib.ClassifyTopology( Proc, Part) + Proc.SlaveProcIndexes = nil + bToReprocess = true + break + elseif ID.IsTailCut( Proc) and not Proc.bIsOriginalTailcut then + Proc.TailProcOriginal.nFlg = 1 + Proc.TailProcOriginal.nIndexMasterProc = nil + Proc.Topology = FeatureLib.ClassifyTopology( Proc, Part) + Proc.SlaveProcIndexes = nil + bToReprocess = true + break + end + end + + -- TODO da capire se dare un tempo molto alto oppure se dare errore perchè non deve mai capitare. Per ora si setta tempo alto + -- se tempo non calcolato, si setta un tempo molto alto, 99 minuti + if not Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine or Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine == 0 then + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99 + end + + if not Proc.AvailableStrategies.dAllStrategiesTotalTime then + Proc.AvailableStrategies.dAllStrategiesTotalTime = 0 + end + Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine + -- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa + if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Completed' then + break + end + + -- se non trovo i file della strategia (Script e Config), scrivo che non è più disponibile + else + Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {} + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found' + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus = 'Not-Applicable' end end - -- si riprocessano le strategie dopo che sono stati letti i parametri - Proc.AvailableStrategies = BCS.UpdateStrategies( Proc.AvailableStrategies) - end - - -- ciclo tutte le strategie della feature - for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do - -- eseguo file config con i parametri di default - local CurrentStrategy = {} - CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) - -- controllo che le librerie siano state effettivamente caricate - if CurrentStrategy.Config and CurrentStrategy.Script then - -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati - _, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy]) - - -- TODO da capire se dare un tempo molto alto oppure se dare errore perchè non deve mai capitare. Per ora si setta tempo alto - -- se tempo non calcolato, si setta un tempo molto alto, 99 minuti - if not Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine or Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine == 0 then - Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99 - end - - if not Proc.AvailableStrategies.dAllStrategiesTotalTime then - Proc.AvailableStrategies.dAllStrategiesTotalTime = 0 - end - Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine - -- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa - if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Completed' then - break - end - - -- se non trovo i file della strategia (Script e Config), scrivo che non è più disponibile - else - Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {} - Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found' - Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus = 'Not-Applicable' + if bToReprocess then + break end + -- si calcola il composite rating delle strategie + Proc.AvailableStrategies = FeatureLib.CalculateStrategiesCompositeRating( Proc.AvailableStrategies, Part.GeneralParameters.GEN_sMachiningStrategy) end - -- si calcola il composite rating delle strategie - Proc.AvailableStrategies = FeatureLib.CalculateStrategiesCompositeRating( Proc.AvailableStrategies, Part.GeneralParameters.GEN_sMachiningStrategy) end end - end + until ( not bToReprocess) or ( nCounter > 5) + return vProcSingleRot end @@ -1382,7 +1410,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation) -- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati local _, Result = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy) -- per i tagli di testa e coda, che non hanno girato nel CalculateStrategies, si devono settare i risultati - if ID.IsHeadCut( Proc) or ID.IsTailCut( Proc) then + if ( ID.IsHeadCut( Proc) or ID.IsTailCut( Proc)) and not Proc.ChosenStrategy.Result then Proc.ChosenStrategy.Result = Result end -- se tutte le strategie disponibili non sono applicabili diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 5ac90dc..d7bc2d0 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -955,7 +955,7 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part) local dNotClampableLengthTail = 0 -- se il grezzo non è definito, prendo il box del pezzo - -- TODO 1- si sta passando b3part per riferimento, 2- non dovrebbe essre sempre definito? + -- TODO 1- si sta passando b3part per riferimento, è giusto? 2- non dovrebbe essre sempre definito? if not Part.b3Raw then Part.b3Raw = Part.b3Part end diff --git a/Strategies/Standard/HEADCUT/HEADCUT.lua b/Strategies/Standard/HEADCUT/HEADCUT.lua index 860ab54..92045a0 100644 --- a/Strategies/Standard/HEADCUT/HEADCUT.lua +++ b/Strategies/Standard/HEADCUT/HEADCUT.lua @@ -22,6 +22,31 @@ local function MakeChamfer() -- TODO funzionalità da aggiungere end +------------------------------------------------------------------------------------------------------------- +local function CalculateHeadCut( Proc, Part) + -- si recuperano gli estremi del box del materiale di testa da togliere + local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head') + local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + + local OptionalParametersBladeToWaste = {} + OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) + OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume + OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath + OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head' + OptionalParametersBladeToWaste.bCannotSplitRestLength = true + + local Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) + if ( not Machinings) or ( #Machinings == 0) then + OptionalParametersBladeToWaste.bReduceBladePath = true + Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + end + + return Machinings +end + ------------------------------------------------------------------------------------------------------------- function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) local StrategyLib = {} @@ -47,7 +72,7 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) end -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) - if Strategy.Parameters.bExecutePreCut then + if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters) -- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra -- if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then @@ -80,7 +105,7 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) local MachiningsToAdd = {} local bExecutePrecutOnly = false -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) - if Strategy.Parameters.bExecutePreCut then + if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then bExecutePrecutOnly = Part.dHeadOverMaterial < 20 if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then @@ -101,25 +126,8 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) if not bExecutePrecutOnly then - -- si recuperano gli estremi del box del materiale di testa da togliere - local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head') - local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) - local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + Strategy.Machining = CalculateHeadCut( Proc, Part) - local OptionalParametersBladeToWaste = {} - OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) - OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume - OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength - OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath - OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head' - OptionalParametersBladeToWaste.bCannotSplitRestLength = true - - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) - -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) - if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then - OptionalParametersBladeToWaste.bReduceBladePath = true - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) - end if Strategy.Machining and #Strategy.Machining > 0 then for i = 1, #Strategy.Machining do local TempList = {} @@ -139,9 +147,17 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) end return bAreAllMachiningsAdded, Strategy.Result - else - return nil, Strategy.Result + + elseif not Proc.bIsOriginalHeadcut then + + Strategy.Machining = CalculateHeadCut( Proc, Part) + + if not Strategy.Machining or #Strategy.Machining == 0 then + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Head machining not possible') + end end + + return nil, Strategy.Result end ------------------------------------------------------------------------------------------------------------- diff --git a/Strategies/Standard/TAILCUT/TAILCUT.lua b/Strategies/Standard/TAILCUT/TAILCUT.lua index 40c999d..e909785 100644 --- a/Strategies/Standard/TAILCUT/TAILCUT.lua +++ b/Strategies/Standard/TAILCUT/TAILCUT.lua @@ -22,6 +22,31 @@ local function MakeChamfer() -- TODO funzionalità da aggiungere end +------------------------------------------------------------------------------------------------------------- +local function CalculateTailCut( Proc, Part) + -- si recuperano gli estremi del box del materiale di coda da rimuovere + local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail') + local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + + local OptionalParametersBladeToWaste = {} + OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) + OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume + OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength + OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath + OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail' + OptionalParametersBladeToWaste.bCannotSplitRestLength = true + + local Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) + if ( not Machinings) or ( #Machinings == 0) then + OptionalParametersBladeToWaste.bReduceBladePath = true + Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) + end + + return Machinings +end + ------------------------------------------------------------------------------------------------------------- function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) local StrategyLib = {} @@ -64,7 +89,7 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) -- se devo rimuovere tutto il restante else -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) - if Strategy.Parameters.bExecutePreCut then + if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then if Part.dRestLength < 20 then bExecutePrecutOnly = true OptionalParameters.dOffset = 0 @@ -119,7 +144,7 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) -- se devo rimuovere tutto il restante else -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) - if Strategy.Parameters.bExecutePreCut then + if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then for i = 1, #Strategy.SplitStrategy do local TempList = {} @@ -140,25 +165,8 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) if not bExecutePrecutOnly then - -- si recuperano gli estremi del box del materiale di coda da rimuovere - local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail') - local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) - local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ()) + Strategy.Machining = CalculateTailCut( Proc, Part) - local OptionalParametersBladeToWaste = {} - OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength) - OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume - OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength - OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath - OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail' - OptionalParametersBladeToWaste.bCannotSplitRestLength = true - - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) - -- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti) - if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then - OptionalParametersBladeToWaste.bReduceBladePath = true - Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste) - end if Strategy.Machining and #Strategy.Machining > 0 then for i = 1, #Strategy.Machining do local TempList = {} @@ -185,9 +193,17 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters) end return bAreAllMachiningsAdded, Strategy.Result - else - return nil, Strategy.Result + + elseif not Proc.bIsOriginalTailcut then + + Strategy.Machining = CalculateTailCut( Proc, Part) + + if not Strategy.Machining or #Strategy.Machining == 0 then + Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Head machining not possible') + end end + + return nil, Strategy.Result end -------------------------------------------------------------------------------------------------------------