diff --git a/Strategies/Standard/STR0005/STR0005.lua b/Strategies/Standard/STR0005/STR0005.lua index 9fcef25..ca2f060 100644 --- a/Strategies/Standard/STR0005/STR0005.lua +++ b/Strategies/Standard/STR0005/STR0005.lua @@ -10,7 +10,7 @@ local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base local BladeToWaste = require( 'BLADETOWASTE') -local FaceByBlade = require( 'FACEBYBLADE') +local BladeKeepWaste = require( 'BLADEKEEPWASTE') -- Tabella per definizione modulo local STR0005 = {} @@ -19,73 +19,8 @@ local Blade = {} Blade.Result = {} ------------------------------------------------------------------------------------------------------------- -local function CompareEdges( EdgeA, EdgeB) - -- prima i lati orientati lungo X - if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then - return true - elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then - return false - -- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato) - else - if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then - return true - elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then - return false - -- se stessa lunghezza si preferiscono i lati più in basso - -- TODO qui dipenderà dalla lama scelta - else - if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then - return true - elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then - return false - -- se stessa Z si preferiscono i lati verso il fronte della trave - else - if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then - return true - elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then - return false - else - return false - end - end - end - end -end -local function SortMachiningsBySegment( MachiningA, MachiningB) - if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then - return false - elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then - return true - -- se segmento uguale, si minimizzano i cambi di lato - else - local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0) - if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then - if bIsOddSegment then - return true - else - return false - end - elseif MachiningA.vtToolDirection:getY() > MachiningB.vtToolDirection:getY() + 10 * GEO.EPS_SMALL then - if bIsOddSegment then - return false - else - return true - end - else - return false - end - end -end - - -function Blade.AddResult( Cutting) - table.insert( Blade.Result, Cutting) - - return Blade.Result -end - function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) -- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) @@ -106,89 +41,22 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) end -- considerazioni necessarie a determinare se lavorare con codolo oppure no - local bLeaveWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'LEAVE_WASTE_ATTACHED') + local bKeepWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'KEEP_WASTE_ATTACHED') local bDropWaste = ( Strategy.Parameters.sCuttingStrategy == 'DROP_WASTE') local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part) local bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN}) -- lavorazione con codolo - if ( not bDropWaste and bFeatureHindersClamping) or bLeaveWasteAttached then - -- TODO valutare se estrapolare in funzione a sè stante in StrategyLibs - -- TODO verificare funzionamento con lama da sotto - -- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????) - -- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo) - - local Cutting1 = {} - local Cutting2 = {} - - -- si trovano i lati da lavorare - local EdgesSorted = {} - for i = 1, #Proc.Faces[1].Edges do - table.insert( EdgesSorted, Proc.Faces[1].Edges[i]) - end - table.sort( EdgesSorted, CompareEdges) - - local dDepthToMachine = EdgesSorted[1].dElevation / 2 - Strategy.Parameters.dStripWidth / 2 - - -- eventuali punti di spezzatura - local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) - local bIsSplitFeature = false - if #FeatureSplittingPoints > 0 then - bIsSplitFeature = true - end - - -- calcolo lavorazioni - -- primo lato - local OptionalParameters = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} - Cutting1 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[1], OptionalParameters) - Blade.AddResult( Cutting1) - -- secondo lato - OptionalParameters.bOppositeToolDirection = true - Cutting2 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[1], OptionalParameters) - Blade.AddResult( Cutting2) - - -- lavorazioni raggruppate in unica lista - Blade.Result.Sorted = {} - for i = 1, #Blade.Result do - if Blade.Result[i].bIsApplicable then - table.insert( Blade.Result.Sorted, Blade.Result[i]) - end - end - - -- aggiunta eventuali lavorazioni splittate - if bIsSplitFeature then - Blade.Result.Sorted = MachiningLib.GetSplitMachinings( Blade.Result.Sorted, FeatureSplittingPoints, Part) - end - - -- ordinamento - table.sort( Blade.Result.Sorted, SortMachiningsBySegment) - - -- calcolo parametri per la stima della velocità di asportazione - -- TODO non è corretto: come si stima la velocità di asportazione con il codolo? è come se avesse rimosso tutto il volume feature nel tempo di percorrenza - if Cutting1.bIsApplicable and Cutting2.bIsApplicable then - MRRParameters1 = { - dStep = TOOLS[Cutting1.nToolIndex].dThickness, - dSideStep = min( TOOLS[Cutting1.nToolIndex].dSideStep, dDepthToMachine), - dFeed = TOOLS[Cutting1.nToolIndex].Feeds.dFeed} - - MRRParameters2 = { - dStep = TOOLS[Cutting2.nToolIndex].dThickness, - dSideStep = min( TOOLS[Cutting2.nToolIndex].dSideStep, dDepthToMachine), - dFeed = TOOLS[Cutting2.nToolIndex].Feeds.dFeed} - - local dMRRBlade1 = MachiningLib.GetToolMRR( MRRParameters1) - local dMRRBlade2 = MachiningLib.GetToolMRR( MRRParameters2) - dMRRBlade = ( dMRRBlade1 + dMRRBlade2) / 2 - - dCompletionPercentage = Cutting2.dCompletionPercentage - else - dMRRBlade = 0 - dCompletionPercentage = 0 - end + if ( not bDropWaste and bFeatureHindersClamping) or bKeepWasteAttached then + local BladeKeepWasteResult + local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth} + Blade.Result.Sorted, BladeKeepWasteResult = BladeKeepWaste.Make( Proc, Part, OptionalParameters) + dMRRBlade = BladeKeepWasteResult.dMRR + dCompletionPercentage = BladeKeepWasteResult.dCompletionPercentage end -- lavorazione a cubetti / taglio singolo - if #Blade.Result == 0 and not bLeaveWasteAttached then + if #Blade.Result == 0 and not bKeepWasteAttached then local dMinZTopBlade local dMaxNyTopBlade local BladeToWasteResult @@ -202,14 +70,15 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters) dMaxWasteLength = Strategy.Parameters.dMaxWasteLength, dMinNzTopBlade = dMinZTopBlade, dMaxNyTopBlade = dMaxNyTopBlade, - bSaveAddedGeometries = bAddMachining + bSaveAddedGeometries = bAddMachining, + dExtendAfterTail = dExtendAfterTail } Blade.Result.Sorted, BladeToWasteResult = BladeToWaste.Make( Proc, Part, OptionalParameters) dMRRBlade = BladeToWasteResult.dMRR dCompletionPercentage = BladeToWasteResult.dCompletionPercentage end - -- aggiunta lavorazioni + -- aggiunta lavorazioni local nIsApplicableCount = 0 local dFinalCompletionPercentage = 100 local bAreAllMachiningsAdded = true diff --git a/Strategies/Standard/STR0005/STR0005Config.lua b/Strategies/Standard/STR0005/STR0005Config.lua index 5a5c0ed..80970e5 100644 --- a/Strategies/Standard/STR0005/STR0005Config.lua +++ b/Strategies/Standard/STR0005/STR0005Config.lua @@ -14,7 +14,7 @@ local STR0005Data = { { sName = 'sCuttingStrategy', sNameNge = 'CUTTING_STRATEGY', sValue = 'AUTO', sType = 'combo', sMinUserLevel = '1', Choices = { { sValue = 'AUTO', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}, { sValue = 'DROP_WASTE', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}, - { sValue = 'LEAVE_WASTE_ATTACHED', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}}, + { sValue = 'KEEP_WASTE_ATTACHED', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}}, { sName = 'dMaxWasteLength', sNameNge = 'MAX_WASTE_LENGTH', sValue = '300', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'}, { sName = 'dMaxWasteVolume', sNameNge = 'MAX_WASTE_VOLUME', sValue = '6000000', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'}, { sName = 'dStripWidth', sNameNge = 'STRIP_WIDTH', sValue = '5', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'}, diff --git a/StrategyLibs/BLADEKEEPWASTE.lua b/StrategyLibs/BLADEKEEPWASTE.lua new file mode 100644 index 0000000..66ee228 --- /dev/null +++ b/StrategyLibs/BLADEKEEPWASTE.lua @@ -0,0 +1,170 @@ +-- BLADEKEEPWASTE.lua by Egalware s.r.l. 2025/03/17 +-- Libreria di supporto a strategie con funzioni comune a strategie diverse. + +-- Tabella per definizione modulo +local BLADEKEEPWASTE = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local FeatureLib = require( 'FeatureLib') +local MachiningLib = require( 'MachiningLib') +-- strategie di base +local FaceByBlade = require('FACEBYBLADE') + +-- tabella per definizione modulo + +------------------------------------------------------------------------------------------------------------- +local function CompareEdges( EdgeA, EdgeB) + -- prima i lati orientati lungo X + if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then + return true + elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then + return false + -- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato) + else + if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then + return false + -- se stessa lunghezza si preferiscono i lati più in basso + -- TODO qui dipenderà dalla lama scelta + else + if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then + return false + -- se stessa Z si preferiscono i lati verso il fronte della trave + else + if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then + return false + else + return false + end + end + end + end +end + + +local function SortMachiningsBySegment( MachiningA, MachiningB) + if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then + return false + elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then + return true + -- se segmento uguale, si minimizzano i cambi di lato + else + local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0) + if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then + if bIsOddSegment then + return true + else + return false + end + elseif MachiningA.vtToolDirection:getY() > MachiningB.vtToolDirection:getY() + 10 * GEO.EPS_SMALL then + if bIsOddSegment then + return false + else + return true + end + else + return false + end + end +end + + +function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters) + -- TODO verificare funzionamento con lama da sotto + -- attenzione perchè se l'inclinazione della faccia la fa finire oltre lo spigolo questo riduce il massimo (come calcolare????) + -- il FindBlade dovrà restituire di utilizzare sempre la lama sopra se l'angolo lo permette, ma avendo un'altezza massima (da macchina) oltre cui il DownUp non sarà fattibile (evita collisioni tra asse e pezzo) + + local Result = {} + local Blade = {} + Blade.Result = {} + local Cutting1 = {} + local Cutting2 = {} + + -- si trovano i lati da lavorare + local EdgesSorted = {} + for i = 1, #Proc.Faces[1].Edges do + table.insert( EdgesSorted, Proc.Faces[1].Edges[i]) + end + table.sort( EdgesSorted, CompareEdges) + + local dDepthToMachine = EdgesSorted[1].dElevation / 2 - OptionalParameters.dStripWidth / 2 + + -- eventuali punti di spezzatura + local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) + local bIsSplitFeature = false + if #FeatureSplittingPoints > 0 then + bIsSplitFeature = true + end + + -- calcolo lavorazioni + -- primo lato + local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = OptionalParameters.dExtendAfterTail} + Cutting1 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[1], OptionalParametersFaceByBlade) + table.insert( Blade.Result, Cutting1) + -- secondo lato + OptionalParametersFaceByBlade.bOppositeToolDirection = true + Cutting2 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[1], OptionalParametersFaceByBlade) + table.insert( Blade.Result, Cutting2) + + -- lavorazioni raggruppate in unica lista + local Machinings = {} + for i = 1, #Blade.Result do + if Blade.Result[i].bIsApplicable then + table.insert( Machinings, Blade.Result[i]) + end + end + + -- aggiunta eventuali lavorazioni splittate + if bIsSplitFeature then + Machinings = MachiningLib.GetSplitMachinings( Machinings, FeatureSplittingPoints, Part) + end + + -- ordinamento + table.sort( Machinings, SortMachiningsBySegment) + + -- calcolo parametri per la stima della velocità di asportazione + -- TODO non è corretto: come si stima la velocità di asportazione con il codolo? è come se avesse rimosso tutto il volume feature nel tempo di percorrenza + if Cutting1.bIsApplicable and Cutting2.bIsApplicable then + MRRParameters1 = { + dStep = TOOLS[Cutting1.nToolIndex].dThickness, + dSideStep = min( TOOLS[Cutting1.nToolIndex].dSideStep, dDepthToMachine), + dFeed = TOOLS[Cutting1.nToolIndex].Feeds.dFeed} + + MRRParameters2 = { + dStep = TOOLS[Cutting2.nToolIndex].dThickness, + dSideStep = min( TOOLS[Cutting2.nToolIndex].dSideStep, dDepthToMachine), + dFeed = TOOLS[Cutting2.nToolIndex].Feeds.dFeed} + + local dMRRBlade1 = MachiningLib.GetToolMRR( MRRParameters1) + local dMRRBlade2 = MachiningLib.GetToolMRR( MRRParameters2) + Result.dMRR = ( dMRRBlade1 + dMRRBlade2) / 2 + Result.dCompletionPercentage = Cutting2.dCompletionPercentage + if Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then + Result.sStatus = 'Completed' + else + Result.sStatus = 'Not-Completed' + end + Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage) + Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') + else + Result.dMRR = 0 + Result.dCompletionPercentage = 0 + Result.sStatus = 'Not-Applicable' + Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage) + Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade') + end + + return Machinings, Result +end + +------------------------------------------------------------------------------------------------------------- + +return BLADEKEEPWASTE \ No newline at end of file diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index b4d105a..c6a74dd 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -281,7 +281,7 @@ 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} + local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = OptionalParameters.dExtendAfterTail} Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) end if Cutting.bIsApplicable then @@ -340,6 +340,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local nToolIndex = OptionalParameters.nToolIndex local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0 local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0 + local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries if bSaveAddedGeometries == nil then bSaveAddedGeometries = true @@ -475,7 +476,8 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, - bDisableHorizontalSteps = true + bDisableHorizontalSteps = true, + dExtendAfterTail = dExtendAfterTail } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) if Cutting.bIsApplicable then @@ -513,7 +515,8 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, EdgeToMachineAlternative = EdgeToMachineAlternative, - bDisableHorizontalSteps = true + bDisableHorizontalSteps = true, + dExtendAfterTail = dExtendAfterTail } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) if Cutting.bIsApplicable then