Files
databeamnew/LuaLibs/StrategyLib.lua
T
andrea.villa cff250ca37 - TAILCUT utilizza nuova libreria
- Prima versione funzionante tagli PRECUT
2024-12-05 08:09:50 +01:00

369 lines
17 KiB
Lua

-- StrategyLib.lua by Egalware s.r.l. 2024/04/02
-- Libreria di supporto a strategie con funzioni comune a strategie diverse.
-- Tabella per definizione modulo
local StrategyLib = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
local FeatureLib = require( 'FeatureLib')
local MachiningLib = require( 'MachiningLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
EgtOutLog( ' StrategyLib started', 1)
-----------------------------------------------------------------------------------
---------------------- FUNZIONI DI SPLIT ------------------------------------------
-----------------------------------------------------------------------------------
StrategyLib.SplitStrategy = {}
function StrategyLib.SplitStrategy.Get( Proc, Part, OptionalParameters)
local Machining = {}
local Result = {}
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
Machining.sTypeMachining = 'None'
local Splitting = {}
-- imposto parametri di ricerca utensile in base a topologia
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
-- ===== RICERCA UTENSILE =====
-- cerco lama sopra
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco lama sotto
Splitting = {}
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco motosega
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- cerco fresa
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- ===== SCELTA LAVORAZIONI =====
-- forzature da parametri
if OptionalParameters.bForceChainSaw then
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
end
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
Result.sStatus = 'Completed'
Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Result.dMRR = 1
-- correzioni sul massimo materiale lama, considerando ingombri vari
local dMaxMatBladeSideSingle
local dMaxMatBladeSideDouble
local dMaxMatBladeHorizontalSingle
local dMaxMatBladeHorizontalDouble
if Machining[1].bIsApplicable then
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
dMaxMatBladeSideSingle = dMaxMat
dMaxMatBladeSideDouble = dMaxMat * 2
else
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
else
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
end
end
-- se taglio orizzontale
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
else
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
end
end
if Machining[2].bIsApplicable then
if BeamData.GetMaxMatReductionBladeCut then
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
else
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
end
end
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Result.dMRR = Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Result.dMRR = Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining, Result
-- TODO : casi con motosega da completare
-- ChainSawHorizontal (motosega)
-- ChainSawSideSingle (motosega)
-- ChainSawSideDouble (motosega)
-- ChainSawPlusBlade (motosega più lama orizzontale)
-- Mill (svuotatura)
end
-- se non ho trovato neanche una lavorazione completa, non posso separare
if Machining.sTypeMachining == 'None' then
Result.sStatus = 'Not-Applicable'
Result.nCompletionIndex = 0
Result.dMRR = 0
Result.nQuality = 0
Result.sInfo = 'Split not possible'
end
return Machining, Result
end
-------------------------------------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, vtEdge)
local Edge
for i = 1, #Proc.Faces[1].Edges do
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
Edge = Proc.Faces[1].Edges[i]
end
end
return Edge
end
-------------------------------------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
LeadIn.nType = MCH_MILL_LI.LINEAR
LeadOut.nType = MCH_MILL_LI.LINEAR
LeadIn.dTangentDistance = 0
LeadOut.dTangentDistance = 0
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-----------------------------------------------------------------------------------
function StrategyLib.SplitStrategy.Execute( Proc, Part, Strategy)
local Machinings = {}
-- applico le lavorazioni
--------------------------------------------------------------------------------
if Strategy.SplitStrategy.sTypeMachining == 'BladeSideSingle' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeSideDouble' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Presplit;', 'Precut;')
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
-- Taglio lato dietro
Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
local Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
local OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
local dExtraMaxMat = ( Strategy.SplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.SplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.SplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Presplit;', 'Precut;')
local EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
-- Taglio lato dietro
Machining = {}
Machining.Splitting = {}
Machining.AuxiliaryData = {}
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.SplitStrategy[2].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
OptionalParameters.sDepth = 0
OptionalParameters.dLongitudinalOffset = Strategy.dOffset or 0
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.SplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
OptionalParameters.sUserNotes = EgtIf( Strategy.bSplit, 'Split;', 'Cut;')
Machining.AuxiliaryData.bAddNewPhase = true
EdgeToMachine = StrategyLib.SplitStrategy.GetEdgeToMachine( Proc, -Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = StrategyLib.SplitStrategy.CalculateLeadInOut( EdgeToMachine)
Machining.Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
table.insert( Machinings, Machining)
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.SplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
; -- TODO
----------------------------------------------------------------------------------
end
return Machinings
end
-------------------------------------------------------------------------------------------------------------
return StrategyLib