Primo commit nuovo automatismo BEAM con strategie
This commit is contained in:
@@ -0,0 +1,623 @@
|
||||
-- BeamExec.lua by Egalware s.r.l. 2024/04/02
|
||||
-- Libreria esecuzione lavorazioni per Travi
|
||||
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local BeamExec = {}
|
||||
|
||||
-- Include
|
||||
require( 'EgtBase')
|
||||
|
||||
-- Carico i dati globali
|
||||
local BD = require( 'BeamData')
|
||||
|
||||
-- carico librerie
|
||||
local BL = require( 'BeamLib')
|
||||
local ID = require( 'Identity')
|
||||
local BCS = require( 'BasicCustomerStrategies')
|
||||
local FD = require( 'FeatureData')
|
||||
|
||||
|
||||
EgtOutLog( ' BeamExec started', 1)
|
||||
EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC)
|
||||
EgtMdbSave()
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** variabili globali ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
TOOLS = nil
|
||||
STRATEGIES = nil
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** COSTANTI *** TODO -> DA SPOSTARE IN BEAMDATA???
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
TH_DIAMETER_HSK63 = 63
|
||||
TH_LENGTH_HSK63 = 75
|
||||
SIDEANGLE_DOVETAIL = 15
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** funzioni di base ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetToolTypeNameFromToolTypeID( dToolTypeID)
|
||||
if dToolTypeID == MCH_TY.DRILL_STD then
|
||||
return 'DRILL_STD', 'DRILLBIT'
|
||||
elseif dToolTypeID == MCH_TY.DRILL_LONG then
|
||||
return 'DRILL_LONG', 'DRILLBIT'
|
||||
elseif dToolTypeID == MCH_TY.SAW_STD then
|
||||
return 'SAW_STD', 'SAWBLADE'
|
||||
elseif dToolTypeID == MCH_TY.SAW_FLAT then
|
||||
return 'SAW_FLAT', 'SAWBLADE'
|
||||
elseif dToolTypeID == MCH_TY.MILL_STD then
|
||||
return 'MILL_STD', 'MILL'
|
||||
elseif dToolTypeID == MCH_TY.MILL_NOTIP then
|
||||
return 'MILL_NOTIP', 'MILL'
|
||||
elseif dToolTypeID == MCH_TY.MORTISE_STD then
|
||||
return 'MORTISE_STD', 'MORTISE'
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function IsToolOk( Tool)
|
||||
-- controllo che i dati necessari siano impostati
|
||||
if Tool.MaxMaterial and Tool.Diameter and Tool.Length and Tool.Head and Tool.UUID then
|
||||
-- se DRILLBIT non ho altri dati
|
||||
if Tool.Family == 'DRILLBIT' then
|
||||
return true
|
||||
-- altrimenti controllo dati aggiuntivi altre famiglie di utensili
|
||||
else
|
||||
if Tool.Thick then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.GetToolsFromDB()
|
||||
-- creo lista globale utensili disponibili
|
||||
TOOLS = {}
|
||||
-- lista appoggio utensile
|
||||
local Tool = {}
|
||||
|
||||
-- recupero tutti gli utensili : punte a forare, lame, frese e motoseghe
|
||||
Tool.Name = EgtTdbGetFirstTool( MCH_TF.DRILLBIT + MCH_TF.SAWBLADE + MCH_TF.MILL + MCH_TF.MORTISE)
|
||||
while Tool.Name ~= '' do
|
||||
-- imposto utensile come corrente per recuperarne i dati
|
||||
EgtTdbSetCurrTool( Tool.Name)
|
||||
|
||||
-- verifico se utensile disponibile in attrezzaggio attuale e che abbia un tipo ben definito
|
||||
local bToolLoadedOnSetup, sToolTCPos = EgtFindToolInCurrSetup( Tool.Name)
|
||||
local dToolTypeID = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
|
||||
local sToolType, sToolFamily = GetToolTypeNameFromToolTypeID( dToolTypeID)
|
||||
|
||||
-- se verifica condizioni minime, recupero tutti gli altri dati
|
||||
if bToolLoadedOnSetup and sToolType then
|
||||
Tool.AName = Tool.Name
|
||||
Tool.TcPos = sToolTCPos
|
||||
Tool.Family = sToolFamily
|
||||
Tool.Type = sToolType
|
||||
Tool.TypeID = dToolTypeID
|
||||
Tool.MaxMaterial = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
||||
Tool.Diameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
||||
Tool.Length = EgtTdbGetCurrToolParam( MCH_TP.LEN)
|
||||
Tool.Speed = EgtTdbGetCurrToolParam( MCH_TP.SPEED)
|
||||
Tool.IsCCW = Tool.Speed < 0
|
||||
Tool.Feeds = {}
|
||||
Tool.Feeds.Feed = EgtTdbGetCurrToolParam( MCH_TP.FEED)
|
||||
Tool.Feeds.StartFeed = EgtTdbGetCurrToolParam( MCH_TP.STARTFEED)
|
||||
Tool.Feeds.EndFeed = EgtTdbGetCurrToolParam( MCH_TP.ENDFEED)
|
||||
Tool.Feeds.TipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED)
|
||||
Tool.Head = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
||||
Tool.UUID = EgtTdbGetCurrToolParam( MCH_TP.UUID)
|
||||
Tool.UserNotes = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES)
|
||||
Tool.MaxDepth = EgtTdbGetCurrToolMaxDepth() or Tool.MaxMaterial
|
||||
Tool.ToolHolder = {}
|
||||
Tool.ToolHolder.Diameter = EgtTdbGetCurrToolThDiam() or TH_DIAMETER_HSK63 -- diametro standard HSK63
|
||||
Tool.ToolHolder.Length = EgtTdbGetCurrToolThLength() or TH_LENGTH_HSK63 -- lunghezza standard HSK63
|
||||
-- parametri scritti nelle note
|
||||
Tool.Double = EgtGetValInNotes( Tool.UserNotes, 'DOUBLE')
|
||||
|
||||
-- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici)
|
||||
if sToolFamily ~= 'DRILLBIT' then
|
||||
Tool.Thick = EgtTdbGetCurrToolParam( MCH_TP.THICK)
|
||||
Tool.LongitudinalOffset = EgtTdbGetCurrToolParam( MCH_TP.LONOFFSET)
|
||||
Tool.RadialOffset = EgtTdbGetCurrToolParam( MCH_TP.RADOFFSET)
|
||||
-- recupero parametri propri delle frese
|
||||
if sToolFamily == 'MILL' then
|
||||
Tool.StemDiameter = EgtTdbGetCurrToolParam( MCH_TP.STEMDIAM) or Tool.ThDiameter -- se non settato, considero diametro come ToolHolder
|
||||
Tool.SideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or 0
|
||||
-- verifico che parametri siano compatibili con una fresa a coda di rondine ( angolo di fianco standard Coda di rondine -> 15°)
|
||||
Tool.IsDoveTail = Tool.Type == 'MILL_NOTIP' and abs( abs( Tool.SideAngle) - SIDEANGLE_DOVETAIL) < 1
|
||||
-- verifico che sia una fresa tipo T-Mill o BlockHaus
|
||||
Tool.SideDepth = EgtGetValInNotes( Tool.UserNotes, 'SIDEDEPTH') or 0 -- se non settato nell'utensile, dico che non ha massimo affondamento laterale
|
||||
Tool.IsTMill = Tool.SideDepth > 0
|
||||
Tool.Step = EgtGetValInNotes( Tool.UserNotes, 'STEP') or ( Tool.MaxMaterial / 2) -- se non settato nell'utensile, considero metà del tagliente
|
||||
Tool.SideStep = EgtGetValInNotes( Tool.UserNotes, 'SIDESTEP') or floor( Tool.Diameter / 2) -- se non settato nell'utensile, considero metà del diametro
|
||||
-- recupero parametri propri delle lame
|
||||
elseif sToolFamily == 'SAWBLADE' then
|
||||
Tool.IsUsedForLongCut = EgtGetValInNotes( Tool.UserNotes, 'LONGCUT') == 1 or false -- false coem valore di default
|
||||
Tool.Step = EgtGetValInNotes( Tool.UserNotes, 'STEP') or Tool.Thick -- se non settato nell'utensile, considero lo spessore lama
|
||||
Tool.SideStep = EgtGetValInNotes( Tool.UserNotes, 'SIDESTEP') or floor( Tool.Diameter / 4) -- se non settato nell'utensile, considero un quarto del diametro
|
||||
-- recupero parametri propri delle motoseghe
|
||||
elseif sToolFamily == 'MORTISE' then
|
||||
Tool.Distance = EgtTdbGetCurrToolParam( MCH_TP.DIST) or 90 -- 90mm dimensione standard aggregato catena
|
||||
Tool.IsMortise = EgtGetValInNotes( Tool.UserNotes, 'MORTISE') == 1
|
||||
Tool.IsChainSaw = not Tool.IsMortise
|
||||
Tool.Step = EgtGetValInNotes( Tool.UserNotes, 'STEP') or ( Tool.Thick - 1) -- se non settato nell'utensile, considero spessore catena meno 1mm di sicurezza
|
||||
Tool.SideStep = EgtGetValInNotes( Tool.UserNotes, 'SIDESTEP') or floor( Tool.MaxMaterial / 3) -- se non settato nell'utensile, considero un terzo della lunghezza
|
||||
end
|
||||
end
|
||||
|
||||
-- se tutti i dati necessari sono disponibili, inserisco utensile nella lista globale degli utensili disponibili
|
||||
if IsToolOk( Tool) then
|
||||
table.insert( TOOLS, Tool)
|
||||
-- altrimenti scrivo nel log che l'utensile non è conforme
|
||||
else
|
||||
EgtOutLog( '*** ' .. Tool.Name .. ' : NOT-COMPLIANT ***', 1)
|
||||
end
|
||||
|
||||
-- reset dati
|
||||
Tool = {}
|
||||
end
|
||||
|
||||
-- recupero utensile successivo ( punte a forare, lame, frese e motoseghe)
|
||||
Tool.Name = EgtTdbGetNextTool( MCH_TF.DRILLBIT + MCH_TF.SAWBLADE + MCH_TF.MILL + MCH_TF.MORTISE)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function ImportFileJSON( sFileToImport)
|
||||
local JSON = require( 'JSON')
|
||||
|
||||
local function readAll( sFileToImport)
|
||||
local f = io.open( sFileToImport, "rb")
|
||||
local content = f:read( "*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
|
||||
local content = readAll( sFileToImport)
|
||||
|
||||
return JSON:decode( content)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.GetStrategiesFromJSONinBD()
|
||||
-- si legge il JSON contenente la configurazione da utilizzare (nome del file salvato nel BeamData)
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if BD.STRATEGIES_CONFIG_FILE then
|
||||
local sFile = sMachDir .. '\\Beam\\' .. BD.STRATEGIES_CONFIG_FILE
|
||||
if not sFile then return end
|
||||
|
||||
local FeaturesList = {}
|
||||
FeaturesList = ImportFileJSON( sFile)
|
||||
|
||||
-- metto la tabella letta nella lista globale STRATEGIES
|
||||
STRATEGIES = {}
|
||||
STRATEGIES.Features = FeaturesList
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** funzioni posizionamento pezzi all'interno della barra ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, vBeam, bMachGroupOk)
|
||||
|
||||
-- default per nuove costanti qualora non definite
|
||||
BD.OVM_BLADE_HBEAM = ( BD.OVM_BLADE_HBEAM or 11)
|
||||
BD.OVM_CHAIN_HBEAM = ( BD.OVM_CHAIN_HBEAM or 8)
|
||||
|
||||
-- sovramateriale intermedio nullo se non definito
|
||||
dOvmMid = ( dOvmMid or 0)
|
||||
|
||||
-- Determinazione minimo grezzo scaricabile
|
||||
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
||||
|
||||
-- Creazione nuovo gruppo di lavoro
|
||||
if not bMachGroupOk then
|
||||
local sMgName = EgtGetMachGroupNewName( 'Mach_1')
|
||||
local NewMgId = EgtAddMachGroup( sMgName)
|
||||
if not NewMgId then
|
||||
local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName
|
||||
return false, sOut
|
||||
end
|
||||
end
|
||||
|
||||
-- Impostazione della tavola
|
||||
EgtSetTable( 'Tab')
|
||||
|
||||
-- salvo nota con lunghezza grezzo
|
||||
-- Recupero l'identificativo del gruppo di lavoro corrente
|
||||
local nMGrpId = EgtGetCurrMachGroup()
|
||||
-- Lunghezza della barra
|
||||
local dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd')
|
||||
if not dBarLen then
|
||||
EgtSetInfo( nMGrpId, 'BARLEN', dRawL)
|
||||
end
|
||||
|
||||
-- Area tavola
|
||||
local b3Tab = EgtGetTableArea()
|
||||
-- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL
|
||||
local dPosY = EgtIf( BD.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BD.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()))
|
||||
BD.OriXR = Point3d( b3Tab:getDimX(), dPosY, 0)
|
||||
BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
|
||||
|
||||
-- Impostazione dell'attrezzaggio di default
|
||||
EgtImportSetup()
|
||||
|
||||
-- Inserimento dei pezzi con il loro grezzo
|
||||
local Cnt = 0
|
||||
local Len = dRawL
|
||||
local nPrevRaw, dPrevDelta
|
||||
local DeltaS = dOvmHead
|
||||
local DeltaSMin = 0
|
||||
local DeltaE = BD.OVM_MID
|
||||
for i = 1, #vBeam do
|
||||
-- assegno identificativo pezzo
|
||||
local Pz = vBeam[i].Id
|
||||
-- dati del pezzo
|
||||
local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT)
|
||||
local b3Solid = vBeam[i].Box
|
||||
if b3Part:isEmpty() or b3Solid:isEmpty() then break end
|
||||
EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3)
|
||||
-- se sezione compatibile e lunghezza disponibile sufficiente
|
||||
local PartLen = b3Solid:getDimX()
|
||||
local PartWidth = b3Solid:getDimY()
|
||||
local PartHeight = b3Solid:getDimZ()
|
||||
local NextLen = Len - DeltaS - PartLen - DeltaE
|
||||
if (( abs( PartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
|
||||
( abs( PartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 100 * GEO.EPS_SMALL)) and
|
||||
NextLen + DeltaE >= 0 then
|
||||
-- eventuale sovramateriale di testa
|
||||
if i > 1 then
|
||||
if vBeam[i].PosX then
|
||||
DeltaS = max( vBeam[i].PosX - ( dRawL - Len), DeltaSMin)
|
||||
else
|
||||
DeltaS = max( dOvmMid - DeltaE, 0)
|
||||
end
|
||||
end
|
||||
-- dimensioni del grezzo
|
||||
local CrawLen = min( PartLen + DeltaS + DeltaE, Len)
|
||||
local Delta = CrawLen - PartLen - DeltaS
|
||||
-- creo e posiziono il grezzo
|
||||
local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL)
|
||||
EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR)
|
||||
EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0))
|
||||
-- assegno ordine in lavorazione
|
||||
Cnt = Cnt + 1
|
||||
EgtSetInfo( nRaw, 'ORD', Cnt)
|
||||
-- creo o pulisco gruppo geometrie aggiuntive
|
||||
if not BL.CreateOrEmptyAddGroup( Pz) then
|
||||
local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz)
|
||||
return false, sOut
|
||||
end
|
||||
-- aggiungo faccia per taglio iniziale al pezzo
|
||||
BL.AddPartStartFace( Pz, b3Solid)
|
||||
-- se sovramateriale di testa, lo notifico
|
||||
if DeltaS > 0.09 then
|
||||
EgtSetInfo( nRaw, 'HOVM', DeltaS)
|
||||
if nPrevRaw then
|
||||
EgtSetInfo( nPrevRaw, 'BDST', DeltaS + dPrevDelta)
|
||||
end
|
||||
end
|
||||
if DeltaE > 0.09 then
|
||||
EgtSetInfo( nRaw, 'TOVM', DeltaE)
|
||||
end
|
||||
-- aggiungo faccia per taglio finale al pezzo
|
||||
BL.AddPartEndFace( Pz, b3Solid)
|
||||
-- inserisco il pezzo nel grezzo
|
||||
EgtDeselectPartObjs( Pz)
|
||||
local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2)
|
||||
EgtAddPartToRawPart( Pz, ptPos, nRaw)
|
||||
if abs( PartWidth - dRawW) > 100 * GEO.EPS_SMALL then
|
||||
-- rotazione attorno a centro geometria complessiva del pezzo
|
||||
EgtRotatePartInRawPart( Pz, X_AX(), 90)
|
||||
-- correggo per eccentricità solido rispetto a geometria complessiva del pezzo
|
||||
local vtEccOri = b3Solid:getCenter() - b3Part:getCenter()
|
||||
local vtEccRot = Vector3d( vtEccOri)
|
||||
vtEccRot:rotate( X_AX(), 90)
|
||||
EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot))
|
||||
end
|
||||
-- aggiorno la lunghezza residua della barra
|
||||
Len = Len - CrawLen
|
||||
-- aggiorno grezzo precedente
|
||||
nPrevRaw = nRaw
|
||||
dPrevDelta = Delta
|
||||
else
|
||||
local sOut = 'Error: part L(' .. EgtNumToString( PartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( Len - 0.1, 1) .. ')'
|
||||
return false, sOut
|
||||
end
|
||||
-- se rimasto troppo poco grezzo, esco
|
||||
--if Len < BD.MinRaw then break end
|
||||
DeltaS = 0
|
||||
end
|
||||
if nPrevRaw then
|
||||
EgtSetInfo( nPrevRaw, 'BDST', 10000)
|
||||
end
|
||||
|
||||
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
||||
if Len > 10 then
|
||||
local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL)
|
||||
EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR)
|
||||
EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0))
|
||||
-- assegno ordine in lavorazione
|
||||
Cnt = Cnt + 1
|
||||
EgtSetInfo( nRaw, 'ORD', Cnt)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
||||
if BD.GetMinUnloadableRaw then
|
||||
BD.MinRaw = BD.GetMinUnloadableRaw( dRawW, dRawH)
|
||||
else
|
||||
local H_S = 200
|
||||
local H_L = 400
|
||||
-- Determinazione minimo grezzo scaricabile
|
||||
if dRawH <= H_S then
|
||||
BD.MinRaw = BD.MINRAW_S
|
||||
elseif dRawH <= H_L then
|
||||
local Coeff = ( dRawH - H_S) / ( H_L - H_S)
|
||||
BD.MinRaw = ( 1 - Coeff) * BD.MINRAW_S + Coeff * BD.MINRAW_L
|
||||
else
|
||||
BD.MinRaw = BD.MINRAW_L
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** Inserimento delle lavorazioni nelle travi ***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local function GetStrategiesFromGlobalList( Proc)
|
||||
-- cerco tra le feature
|
||||
for i = 1, #STRATEGIES.Features do
|
||||
-- se trovo la feature
|
||||
if Proc.Prc == STRATEGIES.Features[i].Prc and Proc.Grp == STRATEGIES.Features[i].Grp then
|
||||
-- cerco tra le topologie
|
||||
for j = 1, #STRATEGIES.Features[i].Topologies do
|
||||
-- se trovo la topologia
|
||||
if Proc.Topology.Name == #STRATEGIES.Features[i].Topologies[j].Name then
|
||||
-- ritorno le strategie disponibili per la feature che sto analizzando
|
||||
return STRATEGIES.Features[i].Topologies[j].Strategies
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetStrategies( Proc)
|
||||
local AvailableStrategiesForProc = {}
|
||||
-- se la lista STRATEGIES è stata letta da JSON (quindi non è vuota), ritorno le strategie possibili
|
||||
if STRATEGIES then
|
||||
AvailableStrategiesForProc = GetStrategiesFromGlobalList( Proc)
|
||||
-- altrimenti lancio script che setta le strategie in modo statico, come definito con cliente
|
||||
else
|
||||
AvailableStrategiesForProc = BCS.GetStrategiesFromBasicCustomerStrategies( Proc)
|
||||
end
|
||||
-- TODO se ci sono strategie, posso caricare qui le varie librerie delle strategie
|
||||
return AvailableStrategiesForProc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetFeatureForcedStrategy( Proc)
|
||||
local ForcedStrategiesForProc = {}
|
||||
local ForcedStrategyForProc = {}
|
||||
local ForcedParametersForProc = {}
|
||||
local ForcedParameter = {}
|
||||
local sStrategyID = EgtGetInfo( Proc.Id, 'STRATEGY', 's')
|
||||
-- se è presente la strategia forzata
|
||||
if sStrategyID then
|
||||
-- importo JSON della strategia per leggere nomi parametri configurabili
|
||||
local sJSONFile = BEAM.BASEDIR .. '\\Strategies\\' .. sStrategyID .. '\\' .. sStrategyID .. '.lua'
|
||||
-- se non trovo file esco
|
||||
if not sJSONFile then return end
|
||||
|
||||
local JSONStrategy = {}
|
||||
JSONStrategy = ImportFileJSON( sJSONFile)
|
||||
|
||||
-- cerco tra le feature del JSON strategia
|
||||
for i = 1, #JSONStrategy.Features do
|
||||
-- se trovo la feature
|
||||
if Proc.Prc == JSONStrategy.Features[i].Prc and Proc.Grp == JSONStrategy.Features[i].Grp then
|
||||
-- cerco tra le topologie
|
||||
for j = 1, #JSONStrategy.Features[i].Topologies do
|
||||
-- se trovo la topologia
|
||||
if Proc.Topology.Name == JSONStrategy.Features[i].Topologies[j].Name then
|
||||
-- leggo i parametri
|
||||
for k = 1, #JSONStrategy.Features[i].Topologies[j].Parameters do
|
||||
local sParameterNameToSearch = sStrategyID .. '_' .. JSONStrategy.Features[i].Topologies[j].Parameters[k].Name
|
||||
-- leggo i parametri configurabili della strategia sulla Proc
|
||||
local xValue = EgtGetInfo( Proc.Id, sParameterNameToSearch, JSONStrategy.Features[i].Topologies[j].Parameters[k].Type)
|
||||
-- salvo in lista il parametro letto se presente, altrimenti prendo quello nel JSON di default. Teoricamernte dovrebbero esserci sempre tutti
|
||||
if xValue then
|
||||
ForcedParameter.Value = xValue
|
||||
else
|
||||
ForcedParameter.Value = JSONStrategy.Features[i].Topologies[j].Parameters[k].Name
|
||||
end
|
||||
ForcedParameter.Name = JSONStrategy.Features[i].Topologies[j].Parameters[k].Name
|
||||
table.insert( ForcedStrategyForProc, ForcedParameter)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ForcedStrategyForProc.StrategyID = sStrategyID
|
||||
ForcedStrategyForProc.Parameters = ForcedParametersForProc
|
||||
-- per il momento sarà sempre e solo una strategia, ma la inserisco comunque in una lista per analogia con gestione standard
|
||||
table.insert( ForcedStrategiesForProc, ForcedStrategyForProc)
|
||||
else
|
||||
ForcedStrategiesForProc = nil
|
||||
end
|
||||
|
||||
return ForcedStrategiesForProc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CollectFeatures( PartId, b3Raw)
|
||||
-- recupero le feature
|
||||
local vProc = {}
|
||||
local LayerId = {}
|
||||
LayerId[1] = BL.GetAddGroup( PartId)
|
||||
LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings')
|
||||
for nInd = 1, 2 do
|
||||
local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL)
|
||||
while ProcId do
|
||||
local nEntType = EgtGetType( ProcId)
|
||||
if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or
|
||||
nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then
|
||||
local nGrp = EgtGetInfo( ProcId, 'GRP', 'i')
|
||||
local nPrc = EgtGetInfo( ProcId, 'PRC', 'i')
|
||||
local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1
|
||||
local nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0
|
||||
local nTaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0
|
||||
-- leggo se ci sono feature collegate
|
||||
local nAddAdjId = EgtGetInfo( ProcId, 'ADJID', 'i')
|
||||
local nAddMainId = EgtGetInfo( ProcId, 'MAINID', 'i')
|
||||
if nGrp and nPrc and nDo == 1 then
|
||||
local Proc = {}
|
||||
Proc.PartId = PartId
|
||||
Proc.Id = ProcId
|
||||
-- id della feature btl ( se non presente info, si prende id dell'entità geometrica)
|
||||
Proc.FeatureId = EgtGetInfo( Proc.Id, 'PRID', 's') or Proc.Id
|
||||
Proc.Grp = nGrp
|
||||
Proc.Prc = nPrc
|
||||
Proc.Flg = 1
|
||||
Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0
|
||||
Proc.CutId = nCutId
|
||||
Proc.TaskId = nTaskId
|
||||
-- se ci sono feature collegate ne scrivo il riferimento nella Proc
|
||||
if nAddAdjId then
|
||||
Proc.AdjId = Proc.Id + nAddAdjId
|
||||
elseif nAddMainId then
|
||||
Proc.MainId = Proc.Id + nAddMainId
|
||||
end
|
||||
Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
|
||||
-- se esiste la geometria
|
||||
if Proc.Box and not Proc.Box:isEmpty() then
|
||||
-- TODO fare una funzione per recuperare i dati delle feature che non passano dal calcolo della topologia?
|
||||
-- se foro calcolo altri dati
|
||||
if ID.IsDrilling( Proc) then
|
||||
-- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento)
|
||||
Proc.Diam, Proc.Len, Proc.Fcs, Proc.Fce = FD.GetDataDrill( Proc)
|
||||
end
|
||||
-- si recupera la topologia della feature
|
||||
Proc.Topology = FD.GetTopology( Proc, b3Raw)
|
||||
-- se topologia feature riconosciuta, oppure da non calcolare perchè il riconoscimento topologico è basato sulla feature stessa
|
||||
if Proc.Topology.Name ~= 'NOT_IMPLEMENTED' then
|
||||
-- TODO Funzione 'GetMainFaces' da scrivere
|
||||
Proc.MainFaces = FD.GetMainFaces( Proc)
|
||||
-- se la processing ha una strategia forzata, riporto tutto nella proc
|
||||
local vForcedStrategy = GetFeatureForcedStrategy( Proc)
|
||||
if vForcedStrategy then
|
||||
Proc.Strategies = vForcedStrategy
|
||||
-- altrimenti cerco tra le strategie disponibili
|
||||
else
|
||||
Proc.Strategies = GetStrategies( Proc)
|
||||
end
|
||||
-- se ci sono strategie disponibili, aggiungo a lista delle feature da lavorare
|
||||
if Proc.Strategies then
|
||||
table.insert( vProc, Proc)
|
||||
-- altrimenti errore (non ci sono strategie per lavorare la topologia riconosciuta)
|
||||
else
|
||||
EgtOutLog( ' Feature ' .. tostring( Proc.FeatureId) .. ' : NO available strategies')
|
||||
end
|
||||
-- altrimenti errore (serviva riconoscimento topologico, ma non è stato possibile farlo)
|
||||
else
|
||||
EgtOutLog( ' Feature ' .. tostring( Proc.FeatureId) .. ' : NO available strategies')
|
||||
end
|
||||
else
|
||||
Proc.Flg = 0
|
||||
table.insert( vProc, Proc)
|
||||
EgtOutLog( ' Feature ' .. tostring( Proc.FeatureId) .. ' is empty (no geometry)')
|
||||
end
|
||||
end
|
||||
end
|
||||
ProcId = EgtGetNext( ProcId)
|
||||
end
|
||||
end
|
||||
return vProc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetFeatureInfoAndDependency( vProc, b3Raw)
|
||||
-- ciclo tutte le feature
|
||||
for i = 1, #vProc do
|
||||
local Proc = vProc[i]
|
||||
-- controllo la feature con tutte le altre per recuperare le dipendenze
|
||||
for j = 1, #vProc do
|
||||
-- non si controlla la feature con se stessa
|
||||
if i ~= j then
|
||||
local ProcB = vProc[j]
|
||||
-- verifico se feature tipo LapJoint è attraversata da almeno un foro
|
||||
if ( Proc.Topology.Family == 'Pocket' or Proc.Topology.Family == 'Tunnel' or Proc.Topology.Family == 'Groove' or ID.IsMortise( Proc)) and
|
||||
ID.IsDrilling( ProcB) and Overlaps( Proc.Box, ProcB.Box) then
|
||||
Proc.PassedByHole = true
|
||||
end
|
||||
-- verifiche per specchiature
|
||||
if BD.DOWN_HEAD or BD.TWO_EQUAL_HEADS then
|
||||
-- forature
|
||||
if BD.DOUBLE_HEAD_DRILLING and ID.IsDrilling( Proc) and ID.IsDrilling( ProcB) and not Proc.Mirror then
|
||||
if AreDrillingsMirrored( Proc, ProcB, b3Raw) then
|
||||
Proc.Mirror = ProcB
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessFeatures()
|
||||
-- ciclo sui pezzi
|
||||
local nTotErr = 0
|
||||
local Stats = {}
|
||||
local nOrd = 1
|
||||
local nRawId = EgtGetFirstRawPart()
|
||||
while nRawId do
|
||||
-- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli
|
||||
local nPartId = EgtGetFirstPartInRawPart( nRawId)
|
||||
if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end
|
||||
-- aggiungo la fase, se non è la prima
|
||||
if nOrd == 1 then
|
||||
EgtSetCurrPhase( 1)
|
||||
else
|
||||
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0)
|
||||
end
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local nDispId = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST'))
|
||||
EgtSetInfo( nDispId, 'ORD', nOrd)
|
||||
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1)
|
||||
-- ingombro del grezzo
|
||||
local b3Raw = EgtGetRawPartBBox( nRawId)
|
||||
-- recupero le feature di lavorazione della trave
|
||||
local vProc = CollectFeatures( nPartId, b3Raw)
|
||||
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
||||
GetFeatureInfoAndDependency( vProc, b3Raw)
|
||||
|
||||
-- TODO ordinare feature e decidere spezzoni
|
||||
-- TODO applicare lavorazioni in base a strategie disponibili (prima applicabile o EgalwareIA in base a parametro)
|
||||
-- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima
|
||||
|
||||
|
||||
EgtOutLog( ' *** End AddMachinings ***', 1)
|
||||
-- passo al grezzo successivo
|
||||
nOrd = nOrd + 1
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
end
|
||||
|
||||
return ( nTotErr == 0), Stats
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
return BeamExec
|
||||
Reference in New Issue
Block a user