084b6758a3
- SLOTBYCHAINSAW rinominata FACEBYCHAINSAW - in SPLITCUT modifiche alle chiamate di FACEBYBLADE per contemplare la nuova funzione - in STR0005 - codolo l'utensile non viene passato ma viene lasciato scegliere alla FACEBYBLADE
238 lines
9.5 KiB
Lua
238 lines
9.5 KiB
Lua
-- Strategia: STR0005
|
|
-- Descrizione
|
|
-- lama per taglio facce con cubetti se necessario
|
|
-- Feature: tagli singoli con eventuali cubetti
|
|
|
|
-- carico librerie
|
|
local BeamLib = require( 'BeamLib')
|
|
local BeamData = require( 'BeamData')
|
|
local MachiningLib = require( 'MachiningLib')
|
|
local FeatureLib = require( 'FeatureLib')
|
|
-- strategie di base
|
|
local BladeToWaste = require( 'BLADETOWASTE')
|
|
local FaceByBlade = require( 'FACEBYBLADE')
|
|
|
|
-- Tabella per definizione modulo
|
|
local STR0005 = {}
|
|
local Strategy = {}
|
|
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ù in basso
|
|
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
|
|
|
|
|
|
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 Blade.AddMachiningAllSteps( Proc, Cutting, AuxiliaryData)
|
|
local bMachiningAdded = false
|
|
if not AuxiliaryData then
|
|
AuxiliaryData = {}
|
|
end
|
|
AuxiliaryData.Clones = {}
|
|
|
|
local dOriginalRadialOffset = Cutting.dRadialOffset
|
|
local dOriginalLeadInPerpDistance = Cutting.LeadIn.dPerpDistance
|
|
local dOriginalLeadOutPerpDistance = Cutting.LeadOut.dPerpDistance
|
|
for i = 1, Cutting.HorizontalSteps.nCount do
|
|
AuxiliaryData.Clones[i] = {}
|
|
AuxiliaryData.Clones[i].LeadIn = {}
|
|
AuxiliaryData.Clones[i].LeadOut = {}
|
|
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.dStep * ( Cutting.HorizontalSteps.nCount - i)
|
|
-- update distanza perpendicolare attacco per contemplare l'offset applicato
|
|
AuxiliaryData.Clones[i].LeadIn.dPerpDistance = dOriginalLeadInPerpDistance - Cutting.dRadialOffset
|
|
AuxiliaryData.Clones[i].LeadOut.dPerpDistance = dOriginalLeadOutPerpDistance - Cutting.dRadialOffset
|
|
end
|
|
bMachiningAdded = MachiningLib.AddNewMachining( Proc, Cutting, AuxiliaryData)
|
|
|
|
return bMachiningAdded
|
|
end
|
|
|
|
|
|
function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
|
|
-- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
|
|
local StrategyLib = {}
|
|
StrategyLib.Config = require( 'STR0005\\STR0005Config')
|
|
Strategy.sName = StrategyLib.Config.sStrategyId
|
|
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
|
|
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
|
|
Strategy.Result = {}
|
|
Strategy.Result.sInfo = ''
|
|
Blade.Result = {}
|
|
|
|
-- estensione oltre la coda
|
|
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
|
|
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
|
|
dExtendAfterTail = 10000
|
|
end
|
|
|
|
local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part)
|
|
local bLeaveWasteAttached = Strategy.Parameters.sCuttingStrategy == 'LEAVE_WASTE_ATTACHED'
|
|
local bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
|
|
local Cutting = {}
|
|
local dMRRBlade = 0
|
|
|
|
if 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
|
|
|
|
-- 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
|
|
Cutting2 = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgesSorted[2], 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
|
|
|
|
table.sort( Blade.Result.Sorted, SortMachiningsBySegment)
|
|
|
|
-- parametri per il calcolo della velocità di asportazione
|
|
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
|
|
|
|
Cutting = Cutting2
|
|
-- se la lavorazione con codolo fallisce o non è possibile si proseguirà a quella con cubetti
|
|
end
|
|
|
|
if #Blade.Result == 0 and not bLeaveWasteAttached then
|
|
-- BladeToWaste
|
|
end
|
|
|
|
-- aggiunta lavorazioni
|
|
local nIsApplicableCount = 0
|
|
local dFinalCompletionPercentage = 100
|
|
local bAreAllMachiningsAdded = true
|
|
for i = 1, #Blade.Result.Sorted do
|
|
if Blade.Result.Sorted[i].bIsApplicable then
|
|
nIsApplicableCount = nIsApplicableCount + 1
|
|
if bAddMachining then
|
|
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Sorted[i])
|
|
if not bIsMachiningAdded then
|
|
bAreAllMachiningsAdded = false
|
|
end
|
|
end
|
|
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Sorted[i].sMessage
|
|
end
|
|
end
|
|
-- TODO calcolo migliore area lavorata; se ho il codolo ha senso l'incompleta? se incompleta con codolo faccio i cubetti??
|
|
if nIsApplicableCount > 0 then
|
|
if Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
|
Strategy.Result.sStatus = 'Completed'
|
|
else
|
|
Strategy.Result.sStatus = 'Not-Completed'
|
|
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
|
|
dFinalCompletionPercentage = Cutting.dCompletionPercentage
|
|
end
|
|
else
|
|
Strategy.Result.sStatus = 'Not-Applicable'
|
|
end
|
|
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
|
|
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
|
|
Strategy.Result.dMRR = dMRRBlade
|
|
|
|
return bAreAllMachiningsAdded, Strategy.Result
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
|
|
return STR0005 |