- Crazione strategie di lavorazione (per ora è una per tipo)

- Rimosso da WinExec gestione strategie derivata da Beam
- Pulita Collect da parametri provenienti da BTL
- ProcessFeature semplitifacta. Non contempla rotazioni/ribaltamenti del pezzo
- Aggiunta libreria delle lavorazioni
- Aggiunta libreria identità di una lavorazione
- Aggiunta libreria recupero informazioni feature
- AlignRawsToTable spostata in ProcessWin (prima era nella macchina)
This commit is contained in:
andrea.villa
2024-06-17 17:09:43 +02:00
parent 51ac46ca73
commit 1c00c1224b
11 changed files with 679 additions and 419 deletions
+44
View File
@@ -0,0 +1,44 @@
-- FeatureData.lua by Egalware s.r.l. 2024/06/18
-- Libreria lettura o calcolo dati e proprietà della feature
-- Tabella per definizione modulo
local FeatureData = {}
-- Carico i dati globali
local WinData = require( 'WinData')
-------------------------------------------------------------------------------------------------------------
-- Recupero dati foro
function FeatureData.GetDrillingData( Proc)
local bOk, ptCentre, vtDir, dRadius = EgtCurveIsACircle( Proc.id)
Proc.dDiam = dRadius * 2
Proc.dLen = abs( EgtCurveThickness( Proc.id)) or 0
Proc.ptCentre = ptCentre
Proc.vtDir = vtDir
return Proc
end
-------------------------------------------------------------------------------------------------------------
-- Recupero dati profilatura
function FeatureData.GetProfilingData( Proc)
-- recupero utensili
Proc.nToolsToUse = EgtGetInfo( Proc.id, 'NTOOLS', 'i') or 0
Proc.Tools = {}
for t = 1, Proc.nToolsToUse do
local Data = {}
Data.sName = EgtGetInfo( Proc.id, 'TOOL_NAME_' .. tostring(t), 's') or 0
Data.dRadialOvermat = EgtGetInfo( Proc.id, 'OFFR_' .. tostring(t), 'd') or 0
Data.dLongitudinalOvermat = EgtGetInfo( Proc.id, 'OFFL_' .. tostring(t), 'd') or 0
Data.sSide = EgtGetInfo( Proc.id, 'N', 's') or 0
table.insert( Proc.Tools, Data)
end
Proc.ProfileType = EgtGetInfo( Proc.id, 'ProfileType', 's') or ''
return Proc
end
-------------------------------------------------------------------------------------------------------------
return FeatureData
+36
View File
@@ -0,0 +1,36 @@
-- Identity.lua by Egalware s.r.l. 2024/06/18
-- Libreria Riconoscimento della feature
-- Tabella per definizione modulo
local Identity = {}
---------------------------------------------------------------------
------------------------ STANDARD FEATURES ------------------------
---------------------------------------------------------------------
-- Feature : Drilling
function Identity.IsDrilling( Proc)
return Proc.sType == 'Hole'
end
---------------------------------------------------------------------
-- Feature : Cutting
function Identity.IsCutting( Proc)
return Proc.sType == 'Cut'
end
---------------------------------------------------------------------
-- Feature : Milling
function Identity.IsMilling( Proc)
return Proc.sType == 'Milling'
end
---------------------------------------------------------------------
-- Feature : Pocketing
function Identity.IsPocketing( Proc)
return Proc.sType == 'Pocket'
end
---------------------------------------------------------------------
-- Feature : Profiling
function Identity.IsProfiling( Proc)
return Proc.sType == 'Profiling'
end
---------------------------------------------------------------------
return Identity
+391
View File
@@ -0,0 +1,391 @@
-- MachiningLib.lua by Egalware s.r.l. 2024/06/17
-- Libreria ricerca lavorazioni per serramenti
-- Tabella per definizione modulo
local MachiningLib = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
EgtOutLog( ' MachiningLib started', 1)
---------------------------------------------------------------------
-- TODO da considerare solo angolo 2D??
local function GetToolEntryAngle( Proc, vtTool)
local Angle = {}
local dSinAngle = -10 * GEO.EPS_SMALL
local vtNorm
if Proc.AffectedFaces.bTop then
vtNorm = Z_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bBottom then
vtNorm = -Z_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bFront then
vtNorm = -Y_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bBack then
vtNorm = Y_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bLeft then
vtNorm = -X_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bRight then
vtNorm = X_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
local dCosAngle = sqrt( 1 - sqr( dSinAngle))
local dAngle = acos( dCosAngle)
local dTanAngle
if dAngle ~= 0 and dAngle ~= 90 then
dTanAngle = sqrt( 1 - dCosAngle * dCosAngle) / dCosAngle
end
Angle.dValue = dAngle
Angle.dSin = dSinAngle
Angle.dCos = dCosAngle
Angle.dTan = dTanAngle
return Angle
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo FRESA con certe caratteristiche
function MachiningLib.FindMill( Proc, ToolSearchParameters)
local ToolInfo = {}
local nBestToolIndex
local dBestToolResidualDepth = 0
for i = 1, #TOOLS do
-- prima verifico che utensile sia compatibile
local bIsToolCompatible = true
if ToolSearchParameters.sName and ToolSearchParameters.sName ~= TOOLS[i].sName then
bIsToolCompatible = false
elseif ToolSearchParameters.dMaxToolDiameter and TOOLS[i].dDiameter > ToolSearchParameters.dMaxToolDiameter then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'STANDARD' and ( TOOLS[i].dSideAngle ~= 0 or TOOLS[i].bIsPen) then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'DOVETAIL' and not TOOLS[i].bIsDoveTail then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'TSHAPEMILL' and not TOOLS[i].bIsTMill then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'PEN' and not TOOLS[i].bIsPen then
bIsToolCompatible = false
elseif ToolSearchParameters.sType and TOOLS[i].sType ~= ToolSearchParameters.sType then
-- se sto cercando una fresa che non può lavorare di testa, quelle che lavorano di testa sono comunque ammesse
if TOOLS[i].sType == 'MILL_STD' and ToolSearchParameters.sType == 'MILL_NOTIP' then
bIsToolCompatible = true
else
bIsToolCompatible = false
end
end
-- scelgo il migliore
if bIsToolCompatible then
-- calcolo riduzione del massimo materiale utilizzabile
local ToolEntryAngle = GetToolEntryAngle( Proc, ToolSearchParameters.vtToolDirection)
-- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore.
local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, BeamData.C_SIMM_ENC)
local dCurrentMaxMatReduction = BeamData.COLL_SIC or 5
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
-- TODO considerare anche il caso in cui lo stelo sia più grande del diametro utensile
-- TODO nei confronti tra valori gestire tolleranze
-- calcolo riduzione per non toccare con ToolHolder / Motore
if ToolEntryAngle.dValue > 0 and ToolEntryAngle.dValue < 90 then
dCurrentMaxMatReduction = dCurrentMaxMatReduction / ToolEntryAngle.dSin + ( ( dDimObjToCheck - TOOLS[i].dDiameter) / 2) / ToolEntryAngle.dTan
end
-- dCurrMachReduction = negativo -> limitare, positivo -> mm extra disponibili
local dCurrentResidualDepth = ToolSearchParameters.dElevation + dCurrentMaxMatReduction - TOOLS[i].dMaxDepth
-- se non ancora trovato, oppure se completo e il migliore fino ad ora non è completo: corrente è il migliore
if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 0) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
-- altrimenti scelgo il migliore
else
-- se entrambi completi
if dBestToolResidualDepth <= 0 and dCurrentResidualDepth <= 0 then
-- se il migliore era su aggregato e corrente montanto direttamente, prediligo utensile montato direttamente
if not TOOLS[i].SetupInfo.bToolOnAggregate and TOOLS[i].SetupInfo.bToolOnAggregate then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
-- se hanno stesso montaggio
elseif TOOLS[i].SetupInfo.bToolOnAggregate == TOOLS[nBestToolIndex].SetupInfo.bToolOnAggregate then
-- scelgo utensile con indice di bontà utensile calcolato come: lunghezza / massimo materiale / diametro
if ( TOOLS[i].dLength / TOOLS[i].dMaxMaterial) / TOOLS[i].dDiameter < ( TOOLS[nBestToolIndex].dLength / TOOLS[nBestToolIndex].dMaxMaterial) / TOOLS[nBestToolIndex].dDiameter then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
-- se entrambi incompleti
elseif dBestToolResidualDepth > 0 and dCurrentResidualDepth > 0 then
--scelgo quello che lavora di più
if dCurrentResidualDepth < dBestToolResidualDepth then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
end
end
end
ToolInfo.nToolIndex = nBestToolIndex
ToolInfo.dResidualDepth = dBestToolResidualDepth
return ToolInfo
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da completare
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {}
-- parametri opzionali
ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0
ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local nBestToolIndex
for i = 1, #TOOLS do
local bIsToolCompatible = false
-- TODO per il momento si prende la prima lama. Da completare
if TOOLS[i].sFamily == 'SAWBLADE' then
bIsToolCompatible = true
end
if bIsToolCompatible then
nBestToolIndex = i
break
end
end
ToolInfo.nToolIndex = nBestToolIndex
return ToolInfo
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche
-- TODO da fare
function MachiningLib.FindDrill()
end
-------------------------------------------------------------------------------------------------------------
-- salva in lista globale la lavorazione appena calcolata
function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd)
-- Controllo parametri obbligatori
if not MachiningToAdd.nType or not MachiningToAdd.nToolIndex or not MachiningToAdd.Geometry or not ProcToAdd.id then
return false
end
-- Drilling
if MachiningToAdd.nType == MCH_MY.DRILLING then
MachiningToAdd.sTypeName = 'Drill_'
-- Milling
elseif MachiningToAdd.nType == MCH_MY.MILLING then
-- se utensile lama
if TOOLS[MachiningToAdd.nToolIndex].sFamily == 'SAWBLADE' then
MachiningToAdd.sTypeName = 'Cut_'
else
MachiningToAdd.sTypeName = 'Mill_'
end
-- Pocketing
elseif MachiningToAdd.nType == MCH_MY.POCKETING then
MachiningToAdd.sTypeName = 'Pocket_'
-- Mortising
elseif MachiningToAdd.nType == MCH_MY.MORTISING then
MachiningToAdd.sTypeName = 'ChSaw_'
end
-- se nome non definito, assegno alla lavorazioen un nome standard
if not MachiningToAdd.sOperationName then
MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) .. '_' .. tostring( MachiningToAdd.Geometry[1][2])
end
if not MachiningToAdd.sToolName then
MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName
end
local Machining = {}
Machining.Proc = ProcToAdd
Machining.Machining = MachiningToAdd
table.insert( MACHININGS, Machining)
return true
end
-------------------------------------------------------------------------------------------------------------
-- funzione per aggiungere una nuova lavorazione
function MachiningLib.AddOperations( vProc, Part)
local nErr
local sErr = ''
local bAreAllMachiningApplyOk = true
for i = 1, #MACHININGS do
-- creazione lavorazione
local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName)
if nOperationId then
-- impostazione geometria
EgtSetMachiningGeometry( MACHININGS[i].Machining.Geometry)
-- impostazione parametri lavorazione
if MACHININGS[i].Machining.sDepth then
EgtSetMachiningParam( MCH_MP.DEPTH_STR, MACHININGS[i].Machining.sDepth)
end
if MACHININGS[i].Machining.bInvert then
EgtSetMachiningParam( MCH_MP.INVERT, MACHININGS[i].Machining.bInvert)
end
if MACHININGS[i].Machining.nWorkside then
EgtSetMachiningParam( MCH_MP.WORKSIDE, MACHININGS[i].Machining.nWorkside)
end
if MACHININGS[i].Machining.nFaceuse then
EgtSetMachiningParam( MCH_MP.FACEUSE, MACHININGS[i].Machining.nFaceuse)
end
if MACHININGS[i].Machining.nSCC then
EgtSetMachiningParam( MCH_MP.SCC, MACHININGS[i].Machining.nSCC)
end
if MACHININGS[i].Machining.bToolInvert then
EgtSetMachiningParam( MCH_MP.TOOLINVERT, MACHININGS[i].Machining.bToolInvert)
end
if MACHININGS[i].Machining.sBlockedAxis then
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, MACHININGS[i].Machining.sBlockedAxis)
end
if MACHININGS[i].Machining.sInitialAngles then
EgtSetMachiningParam( MCH_MP.INITANGS, MACHININGS[i].Machining.sInitialAngles)
end
if MACHININGS[i].Machining.nHeadSide then
EgtSetMachiningParam( MCH_MP.HEADSIDE, MACHININGS[i].Machining.nHeadSide)
end
if MACHININGS[i].Machining.nSubType then
EgtSetMachiningParam( MCH_MP.SUBTYPE, MACHININGS[i].Machining.nSubType)
end
if MACHININGS[i].Machining.dOverlap then
EgtSetMachiningParam( MCH_MP.OVERL, MACHININGS[i].Machining.dOverlap)
end
-- step
if MACHININGS[i].Machining.Steps then
if MACHININGS[i].Machining.Steps.dStepType then
EgtSetMachiningParam( MCH_MP.STEPTYPE, MACHININGS[i].Machining.Steps.dStepType)
end
if MACHININGS[i].Machining.Steps.dStep then
EgtSetMachiningParam( MCH_MP.STEP, MACHININGS[i].Machining.Steps.dStep)
end
if MACHININGS[i].Machining.Steps.dSideStep then
EgtSetMachiningParam( MCH_MP.SIDESTEP, MACHININGS[i].Machining.Steps.dSideStep)
end
end
if MACHININGS[i].Machining.dStartPos then
EgtSetMachiningParam( MCH_MP.STARTPOS, MACHININGS[i].Machining.dStartPos)
end
if MACHININGS[i].Machining.dReturnPos then
EgtSetMachiningParam( MCH_MP.RETURNPOS, MACHININGS[i].Machining.dReturnPos)
end
if MACHININGS[i].Machining.dRadialOffset then
EgtSetMachiningParam( MCH_MP.OFFSR, MACHININGS[i].Machining.dRadialOffset)
end
if MACHININGS[i].Machining.dLongitudinalOffset then
EgtSetMachiningParam( MCH_MP.OFFSL, MACHININGS[i].Machining.dLongitudinalOffset)
end
-- paraemtri attacco
if MACHININGS[i].Machining.LeadIn then
if MACHININGS[i].Machining.LeadIn.nType then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MACHININGS[i].Machining.LeadIn.nType)
end
if MACHININGS[i].Machining.LeadIn.dStartAddLength then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, MACHININGS[i].Machining.LeadIn.dStartAddLength)
end
if MACHININGS[i].Machining.LeadIn.dTangentDistance then
EgtSetMachiningParam( MCH_MP.LITANG, MACHININGS[i].Machining.LeadIn.dTangentDistance)
end
if MACHININGS[i].Machining.LeadIn.dPerpDistance then
EgtSetMachiningParam( MCH_MP.LIPERP, MACHININGS[i].Machining.LeadIn.dPerpDistance)
end
if MACHININGS[i].Machining.LeadIn.dElevation then
EgtSetMachiningParam( MCH_MP.LIELEV, MACHININGS[i].Machining.LeadIn.dElevation)
end
if MACHININGS[i].Machining.LeadIn.dCompLength then
EgtSetMachiningParam( MCH_MP.LICOMPLEN, MACHININGS[i].Machining.LeadIn.dCompLength)
end
end
-- parametri uscita
if MACHININGS[i].Machining.LeadOut then
if MACHININGS[i].Machining.LeadOut.nType then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MACHININGS[i].Machining.LeadOut.nType)
end
if MACHININGS[i].Machining.LeadOut.dEndAddLength then
EgtSetMachiningParam( MCH_MP.ENDADDLEN, MACHININGS[i].Machining.LeadOut.dEndAddLength)
end
if MACHININGS[i].Machining.LeadOut.dTangentDistance then
EgtSetMachiningParam( MCH_MP.LOTANG, MACHININGS[i].Machining.LeadOut.dTangentDistance)
end
if MACHININGS[i].Machining.LeadOut.dPerpDistance then
EgtSetMachiningParam( MCH_MP.LOPERP, MACHININGS[i].Machining.LeadOut.dPerpDistance)
end
if MACHININGS[i].Machining.LeadOut.dElevation then
EgtSetMachiningParam( MCH_MP.LOELEV, MACHININGS[i].Machining.LeadOut.dElevation)
end
if MACHININGS[i].Machining.LeadOut.dCompLength then
EgtSetMachiningParam( MCH_MP.LOCOMPLEN, MACHININGS[i].Machining.LeadOut.dCompLength)
end
end
if MACHININGS[i].Machining.dStartSlowLen then
EgtSetMachiningParam( MCH_MP.STARTSLOWLEN, MACHININGS[i].Machining.dStartSlowLen)
end
if MACHININGS[i].Machining.dEndSlowLen then
EgtSetMachiningParam( MCH_MP.ENDSLOWLEN, MACHININGS[i].Machining.dEndSlowLen)
end
if MACHININGS[i].Machining.dThrouAddLen then
EgtSetMachiningParam( MCH_MP.THROUADDLEN, MACHININGS[i].Machining.dThrouAddLen)
end
-- parametri da settare nelle note di sistema
-- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni
local sSystemNotes = EgtGetMachiningParam( MCH_MP.SYSNOTES)
--if MACHININGS[i].Machining.nMachiningOrder then
-- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder)
--end
EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes)
-- parametri da settare nelle note utente
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
if MACHININGS[i].Machining.dMaxElev then
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', MACHININGS[i].Machining.dMaxElev)
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
local bIsApplyOk = MachiningLib.ApplyMachining( true, false)
if not bIsApplyOk then
bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false)
end
else
return false, 'UNEXPECTED ERROR: Error on creating machining'
end
end
return bAreAllMachiningApplyOk, sErr
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.ApplyMachining( bRecalc, bApplyPost)
local bResult = EgtApplyMachining( bRecalc, bApplyPost)
return bResult
end
-------------------------------------------------------------------------------------------------------------
return MachiningLib
+57 -415
View File
@@ -9,6 +9,9 @@ require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
local WinLib = require( 'WinLib')
local ID = require( 'Identity')
local FeatureData = require( 'FeatureData')
EgtOutLog( ' WinExec started', 1)
EgtMdbSave()
@@ -17,7 +20,6 @@ EgtMdbSave()
-- *** variabili globali ***
-------------------------------------------------------------------------------------------------------------
TOOLS = nil
STRATEGIES = nil
MACHININGS = nil
-------------------------------------------------------------------------------------------------------------
@@ -183,81 +185,11 @@ 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.nPrc == STRATEGIES.Features[i].nPrc and Proc.nGrp == STRATEGIES.Features[i].nGrp then
-- cerco tra le topologie
for j = 1, #STRATEGIES.Features[i].Topologies do
-- se trovo la topologia
if Proc.Topology.sName == STRATEGIES.Features[i].Topologies[j].sName 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 = nil
-- se la lista STRATEGIES è stata letta da JSON (quindi non è vuota), ritorno le strategie possibili
if STRATEGIES and #STRATEGIES.Features > 0 then
AvailableStrategiesForProc = GetStrategiesFromGlobalList( Proc)
end
-- se non ho trovato strategie disponibili nel JSON, o se JSON non presente, lancio script che setta le strategie in modo statico, come definito con cliente
if not AvailableStrategiesForProc then
AvailableStrategiesForProc = BCS.GetStrategiesFromBasicCustomerStrategies( Proc)
end
return AvailableStrategiesForProc
end
-------------------------------------------------------------------------------------------------------------
local function GetFeatureForcedStrategy( Proc)
-- cerco nelle note se è stata forzata una strategia specifica
local sStrategyId = EgtGetInfo( Proc.id, 'STRATEGY', 's')
-- se è presente la strategia forzata
if sStrategyId then
-- eseguo file config con i parametri di default
local StrategyData = require( sStrategyId .. '\\' .. sStrategyId .. 'Config')
-- se ID strategia non esiste oppure ID letto in NGE è differente da quello letto nella strategia, esco subito
if not StrategyData or StrategyData.sStrategyId ~= sStrategyId then
return nil
end
-- salvo che questa strategia è stata forzata, e che quindi ho già letto il file config con i parametri di default
-- quando si calcolerà la lavorazione non servirà leggere/riverificare i parametri di default
StrategyData.bForcedStrategy = true
-- cerco e aggiorno i parametri come sono settati nel processing
for i = 1, #StrategyData.Parameters do
local sParameterToRead = StrategyData.sStrategyId .. '_' .. StrategyData.Parameters[i].sName
ForcedParameterForProc = EgtGetInfo( Proc.id, sParameterToRead, 's')
-- se ho trovato il valore, lo sovrascrivo al default
if ForcedParameterForProc then
StrategyData.Parameters[i].sValue = ForcedParameterForProc
end
end
-- ritorno la lista strategia con parametri
local StrategyToProc = {}
table.insert( StrategyToProc, StrategyData)
return StrategyToProc
end
return nil
end
-------------------------------------------------------------------------------------------------------------
local function CollectFeatures( Part)
-- recupero le feature
local vProc = {}
local LayerId = {}
LayerId[1] = BeamLib.GetAddGroup( Part.id)
LayerId[1] = WinLib.GetAddGroup( Part.id)
LayerId[2] = EgtGetFirstNameInGroup( Part.id or GDB_ID.NULL, 'Processings')
for nInd = 1, 2 do
local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL)
@@ -265,65 +197,40 @@ local function CollectFeatures( Part)
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 sType = EgtGetInfo( ProcId, 'FEATURE_TYPE', 's')
local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1
if nGrp and nPrc and nDo == 1 then
if sType and nDo == 1 then
local Proc = {}
Proc.idPart = Part.id
Proc.id = ProcId
-- id della feature btl ( se non presente info, si prende id dell'entità geometrica)
Proc.idFeature = EgtGetInfo( Proc.id, 'PRID', 's') or Proc.id
Proc.nGrp = nGrp
Proc.nPrc = nPrc
Proc.nFlg = 1
Proc.nFct = EgtSurfTmFacetCount( ProcId) or 0
Proc.idCut = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0
Proc.idTask = EgtGetInfo( ProcId, 'TASKID', 'i') or 0
Proc.sType = sType
Proc.b3Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
EgtOutLog( '------Feature ' .. Proc.idFeature .. '------')
Proc.nPhase = EgtGetInfo( ProcId, 'PHASE', 'i') or nil
-- se esiste la geometria
if Proc.b3Box and not Proc.b3Box:isEmpty() then
-- TODO fare una funzione per recuperare i dati delle feature che non passano dal calcolo della topologia?
-- se foro calcolo altri dati
-- calcolo dati specifici per tipologia di feature / lavorazione
-- se foro
if ID.IsDrilling( Proc) then
-- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento)
Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureData.GetDrillingData( Proc)
Proc = FeatureData.GetDrillingData( Proc)
end
-- informazioni facce e topologia
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
-- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL
Proc.Topology = {}
if FeatureData.NeedTopologyFeature( Proc) then
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
Proc.Topology = FeatureData.ClassifyTopology( Proc, Part)
else
Proc.Topology.sFamily = 'FEATURE'
Proc.Topology.sName = 'FEATURE'
-- se taglio
if ID.IsCutting( Proc) then
end
-- se topologia feature riconosciuta, oppure da non calcolare perchè il riconoscimento topologico è basato sulla feature stessa
if Proc.Topology.sName ~= 'NOT_IMPLEMENTED' then
Proc.MainFaces = FaceData.GetMainFaces( Proc, Part)
-- se la processing ha una strategia forzata, riporto tutto nella proc
local vForcedStrategy = GetFeatureForcedStrategy( Proc)
if vForcedStrategy then
Proc.AvailableStrategies = vForcedStrategy
-- altrimenti cerco tra le strategie disponibili
else
Proc.AvailableStrategies = GetStrategies( Proc)
end
-- se ci sono strategie disponibili, aggiungo a lista delle feature da lavorare
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
table.insert( vProc, Proc)
-- altrimenti errore (non ci sono strategie per lavorare la topologia riconosciuta)
else
EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies')
end
-- altrimenti errore (serviva riconoscimento topologico, ma non è stato possibile farlo)
else
EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies')
-- se fresatura
if ID.IsMilling( Proc) then
end
-- se svuotatura
if ID.IsPocketing( Proc) then
end
-- se profilatura
if ID.IsProfiling( Proc) then
Proc = FeatureData.GetProfilingData( Proc)
end
-- inserisco feature in lista
table.insert( vProc, Proc)
else
Proc.nFlg = 0
table.insert( vProc, Proc)
@@ -338,152 +245,30 @@ local function CollectFeatures( Part)
end
-------------------------------------------------------------------------------------------------------------
local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
local function GetFeatureInfoAndDependency( vProc, Part)
-- ciclo tutte le feature
for i = 1, #vProcSingleRot do
local Proc = vProcSingleRot[i]
for i = 1, #vProc do
local Proc = vProc[i]
-- controllo la feature con tutte le altre per recuperare le dipendenze
for j = 1, #vProcSingleRot do
for j = 1, #vProc do
-- non si controlla la feature con se stessa
if i ~= j then
local ProcB = vProcSingleRot[j]
-- verifico se feature tipo LapJoint è attraversata da almeno un foro
if ( Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Groove' or ID.IsMortise( Proc)) and
ID.IsDrilling( ProcB) and Overlaps( Proc.b3Box, ProcB.b3Box) then
Proc.bPassedByHole = true
end
-- verifiche per specchiature
if BeamData.DOWN_HEAD or BeamData.TWO_EQUAL_HEADS then
-- forature
if BeamData.DOUBLE_HEAD_DRILLING and ID.IsDrilling( Proc) and ID.IsDrilling( ProcB) and not Proc.Mirror then
if AreDrillingsMirrored( Proc, ProcB, Part) then
Proc.Mirror = ProcB
end
end
end
local ProcB = vProc[j]
end
end
end
return vProcSingleRot
end
-------------------------------------------------------------------------------------------------------------
local function RunStrategyLibraries( sStrategyId)
local StrategyConfigName = sStrategyId .. '\\' .. sStrategyId .. 'Config'
local StrategyConfigPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyConfigName .. '.lua'
local StrategyScriptName = sStrategyId .. '\\' .. sStrategyId
local StrategyScriptPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyScriptName .. '.lua'
local StrategyLib = {}
if EgtExistsFile( StrategyConfigPath) and EgtExistsFile( StrategyScriptPath) then
StrategyLib.Config = require( StrategyConfigName)
-- eseguo file script strategia
StrategyLib.Script = require( StrategyScriptName)
return StrategyLib
else
return {}
end
end
-------------------------------------------------------------------------------------------------------------
-- ritorna l'indice della strategia migliore, tra le due passate
local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1, nIndex2)
local dChosenIndex = 0
-- controllo indici
if nIndex1 == 0 and nIndex2 == 0 then
dChosenIndex = 0
elseif nIndex1 == 0 then
-- basta che sia applicabile
if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then
dChosenIndex = nIndex2
end
elseif nIndex2 == 0 then
-- basta che sia applicabile
if AvailableStrategies[nIndex1].Result and ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' or AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed') then
dChosenIndex = nIndex1
end
elseif not AvailableStrategies[nIndex1].Result or not AvailableStrategies[nIndex2].Result then
dChosenIndex = 0
elseif ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].Result.sStatus == 'Not-Applicable') then
dChosenIndex = nIndex1
elseif ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' and AvailableStrategies[nIndex1].Result.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then
dChosenIndex = nIndex2
else
-- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete)
if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and
AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.nQuality * AvailableStrategies[nIndex1].Result.nCompletionIndex * AvailableStrategies[nIndex1].Result.dMRR
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.nQuality * AvailableStrategies[nIndex2].Result.nCompletionIndex * AvailableStrategies[nIndex2].Result.dMRR
-- si predilige strategia con rating composito più alto
if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then
dChosenIndex = nIndex1
elseif dCompositeRatingStrategy2 > dCompositeRatingStrategy1 then
dChosenIndex = nIndex2
-- altrimenti si prende la strategia con indice più basso
else
dChosenIndex = EgtIf( nIndex1 < nIndex2, nIndex1, nIndex2)
end
end
end
return dChosenIndex
end
-------------------------------------------------------------------------------------------------------------
-- funzione che processa tutte le feature sul pezzo e trova la miglior strategia di lavorazione tra quelle disponibili
local function GetBestStrategy( 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
local nIndexBestStrategy = 0
-- 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
local bStrategyOk
-- 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].Parameters)
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
-- se scelta strategia standard, esco subito alla prima che trovo completa
-- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then
if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then
break
end
end
-- se non trovo i file della strategia, scrivo che non è più disponibile
else
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {}
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found'
end
end
-- salvo sulla proc la migliore strategia
if nIndexBestStrategy ~= 0 then
Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy]
end
end
end
end
return vProcSingleRot
return vProc
end
-------------------------------------------------------------------------------------------------------------
-- Ordina le feature in base a fase di lavorazione
-- 1) Head : ( intestatura)
-- 2) Standard : ( lavorazioni standard che non impattano sulal coda)
-- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo)
-- 4) Split : ( taglio di separazione)
-- 5) Tail : ( lavorazioni di coda, fatte dopo il taglio di separazione)
-- L'ordine è indicativamente:
-- 1) Fori
-- 2) Scassi serratura/maniglia
-- 3) Profili testa
-- 4) Profili Lati
-- 5) Incontri/scontri
-- TODO Ordinamento da fare
local function OrderFeatures( vProc)
local vProcToSort = vProc
-- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1
@@ -494,31 +279,10 @@ local function OrderFeatures( vProc)
-- se entrambi disabilitati seguo l'Id
elseif B1.nFlg == 0 and B2.nFlg == 0 then
return ( B1.id < B2.id)
-- se in rotazioni diverse, si mette in ordine di rotazioni
elseif B1.nRot ~= B2.nRot then
return ( B1.nRot < B2.nRot)
-- se primo è taglio di testa, va prima degli altri casi
elseif B1.Head and ( B2.Standard or B2.AdvanceTail or B2.Split or B2.Tail) then
elseif B1.nPhase and B2.nPhase and B1.nPhase < B2.nPhase then
return true
-- se primo è taglio standard, va prima degli altri casi
elseif B1.Standard and ( B2.AdvanceTail or B2.Split or B2.Tail) then
elseif B1.nPhase and B2.nPhase and B2.nPhase < B1.nPhase then
return true
-- se primo è taglio di testa anticipata, va prima degli altri casi
elseif B1.AdvanceTail and ( B2.Split or B2.Tail) then
return true
-- se primo è taglio di separazione, va prima delle lavorazioni di coda
elseif B1.Split and B2.Tail then
return true
-- se da lavorare in stessa fase pezzo
elseif B1.Head == B2.Head or B1.Standard == B2.Standard or B1.AdvanceTail == B2.AdvanceTail or B1.Split == B2.Split or B1.Tail == B2.Tail then
-- confronto standard
if abs( B1.b3Box:getCenter():getX() - B2.b3Box:getCenter():getX()) > 0.4 * ( B1.b3Box:getDimX() + B2.b3Box:getDimX()) then
return B1.b3Box:getCenter():getX() > B2.b3Box:getCenter():getX()
elseif abs( B1.b3Box:getCenter():getY() - B2.b3Box:getCenter():getY()) > 0.2 * ( B1.b3Box:getDimY() + B2.b3Box:getDimY()) then
return B1.b3Box:getCenter():getY() > B2.b3Box:getCenter():getY()
elseif abs( B1.b3Box:getCenter():getZ() - B2.b3Box:getCenter():getZ()) > 0.1 * ( B1.b3Box:getDimZ() + B2.b3Box:getDimZ()) then
return B1.b3Box:getCenter():getZ() > B2.b3Box:getCenter():getZ()
end
-- altrimenti si inverte
else
return false
@@ -551,23 +315,10 @@ local function OrderFeatures( vProc)
end
-------------------------------------------------------------------------------------------------------------
-- esegue le strategie migliori che ha precedentemente scelto
local function CalculateMachinings( vProc, Part)
local bAreAllApplyOk = true
MACHININGS = {}
-- applico le strategie scelte
for i = 1, #vProc do
-- processo tutte le feature attive applicando le lavorazioni
local Proc = vProc[i]
if Proc.nFlg ~= 0 and Proc.ChosenStrategy then
-- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia)
local StrategyScriptName = Proc.ChosenStrategy.sStrategyId .. '\\' .. Proc.ChosenStrategy.sStrategyId
local StrategyScript = require( StrategyScriptName)
-- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
bAreAllApplyOk, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy.Parameters)
end
end
return vProc
-- applica le lavorazioni
local function AddMachinings( Proc, Part)
-- TODO applicare lavorazioni!!
return Proc
end
-------------------------------------------------------------------------------------------------------------
@@ -575,16 +326,7 @@ local function PrintFeatures( vProc, Part)
EgtOutLog( ' RawBox=' .. tostring( Part.RawBox))
for i = 1, #vProc do
local Proc = vProc[i]
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s',
Proc.id, Proc.nGrp, Proc.nPrc, Proc.idTask, Proc.idCut,
Proc.nFlg, EgtIf( Proc.bDown, 'T', 'F'), EgtIf( Proc.bSide, 'T', 'F'),
EgtIf( Proc.bHead, 'T', 'F'), EgtIf( Proc.bTail, 'T', EgtIf( Proc.bAdvTail, 'A', 'F')),
Proc.nFcs, Proc.nFce, Proc.dDiam, Proc.nFct, tostring( Proc.b3Box), Proc.Topology.sName or '')
-- info speciali per Block Haus Half Lap
if Proc.nPrc == 37 then
local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.bHeadDir, 'T', 'F'))
sOut = sOut .. sSpec
end
local sOut = string.format( 'Id=%3d Flg=%2d Type=%s', Proc.id, Proc.nFlg, Proc.sType)
EgtOutLog( sOut)
end
end
@@ -598,109 +340,29 @@ function WinExec.ProcessFeatures( PARTS)
local Part = {}
for nPart = 1, #PARTS do
if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end
-- per ogni rotazione, calcolo come lavorare le feature per decidere posizionamento iniziale e in che rotazione verranno lavorate le singole feature
local vProcRot = {}
-- lista contenente le feature da eseguire
local vProc = {}
-- recupero le feature di lavorazione della trave
vProc = CollectFeatures( PARTS[nPart])
-- TODO da rimuovere o lasciare solo per debug
if EgtGetDebugLevel() >= 3 then
EgtStartCounter()
end
-- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato
for dRotIndex = 1, 4 do
-- recupero le feature di lavorazione della trave
table.insert( vProcRot, CollectFeatures( PARTS[nPart]))
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart])
-- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies)
vProcRot[dRotIndex] = GetBestStrategy( vProcRot[dRotIndex], PARTS[nPart])
-- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione
-- vettore movimento grezzi per rotazione di 90deg ogni step
local dDeltaYZ = PARTS[nPart].b3Raw:getDimY() - PARTS[nPart].b3Raw:getDimZ()
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
local bPreMove = ( dDeltaYZ < 0)
-- ruoto le travi della fase corrente
if bPreMove then
EgtMoveRawPart( PARTS[nPart].idRaw, vtMove)
end
EgtRotateRawPart( PARTS[nPart].idRaw, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90))
if not bPreMove then
EgtMoveRawPart( PARTS[nPart].idRaw, vtMove)
end
-- aggiorno info pezzo
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
end
-- TODO da rimuovere o lasciare solo per debug
if EgtGetDebugLevel() >= 3 then
local timeCollect = EgtStopCounter()
timeCollect = timeCollect + 0
EgtOutBox( timeCollect, 'Collect calculation time')
EgtStartCounter()
end
-- TODO decidere come lavorare ogni feature in base alla matrice delle rotazioni
-- la matrice delle rotazioni deve già salvare sulla proc la strategia da utilizzare
-- Conviene salvarsi tutti i dati fino alla lavorazione e il ciclo di applicazione va ad applicare senza calcolare?
-- aggiungo la fase, se non è la prima
if nOrd == 1 then
EgtSetCurrPhase( 1)
else
BeamLib.AddPhaseWithRawParts( PARTS[nPart], BeamData.ptOriXR, BeamData.dPosXR, 0)
end
local nPhase = EgtGetCurrPhase()
local nDispId = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( nDispId, 'TYPE', EgtIf( PARTS[nPart].id, 'START', 'REST'))
EgtSetInfo( nDispId, 'ORD', nOrd)
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
vProc = GetFeatureInfoAndDependency( vProc, PARTS[nPart])
-- debug
if EgtGetDebugLevel() >= 1 then
PrintFeatures( vProc, PARTS[nPart])
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna
vProc = vProcRot[1]
-- ordino le features
vProc = OrderFeatures( vProc)
-- TODO da fare
MACHININGS = {}
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
CalculateMachinings( vProc, PARTS[nPart])
-- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima
-- ordino le lavorazioni
-- OrderMachining( vProc, PARTS[nPart])
-- aggiunge effettivamente le lavorazioni
MachiningLib.AddOperations( vProc, PARTS[nPart])
-- TODO da rimuovere o lasciare solo per debug
if EgtGetDebugLevel() >= 3 then
local timeMachining = EgtStopCounter()
timeMachining = timeMachining + 0
EgtOutBox( timeMachining, 'Machining calculation time')
end
EgtOutLog( ' *** AddMachinings ***', 1)
for i = 1, #vProc do
-- aggiunge le lavorazioni
AddMachinings( vProc[i], PARTS[nPart])
end
EgtOutLog( ' *** End AddMachinings ***', 1)
-- passo al grezzo successivo
@@ -710,29 +372,9 @@ end
-- Aggiornamento finale di tutto
EgtSetCurrPhase( 1)
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
-- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo)
if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then
EgtOutLog( ' **** RECALC ****')
bApplOk, sApplErrors, _ = EgtApplyAllMachinings()
EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC')
end
if not bApplOk then
nTotErr = nTotErr + 1
table.insert( Stats, {nErr = 1, sMsg=sApplErrors, nRot=0, idCut=0, idTask=0})
elseif sApplWarns and #sApplWarns > 0 then
local vLine = EgtSplitString( sApplWarns, '\r\n')
for i = 1, #vLine do
local nPos = vLine[i]:find( '(WRN', 1, true)
if nPos then
local sData = vLine[i]:sub( nPos + 1, -2)
local vVal = EgtSplitString( sData, ',')
local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i')
local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i')
if nWarn and nCutId then
table.insert( Stats, { nErr=-nWarn, sMsg=vLine[i], nRot=0, idCut=nCutId, idTask=0})
end
end
end
table.insert( Stats, {nErr = 1, sMsg=sApplErrors})
end
return ( nTotErr == 0), Stats
+14
View File
@@ -10,6 +10,20 @@ local WinData = require( 'WinData')
EgtOutLog( ' WinLib started', 1)
-------------------------------------------------------------------------------------------------------------
function WinLib.GetAddGroup( PartId)
-- recupero il nome del gruppo di lavoro corrente
local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL)
if not sMchGrp then
return nil, nil
end
-- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco
local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp)
-- restituisco Id e Nome
return AddGrpId, sMchGrp
end
-------------------------------------------------------------------------------------------------------------
return WinLib
+31 -4
View File
@@ -40,6 +40,7 @@ EgtOutLog( '*** Window Process Start ***', 1)
_G.package.loaded.WinData = nil
_G.package.loaded.WinExec = nil
_G.package.loaded.WinLib = nil
_G.package.loaded.FeatureData = nil
-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente
-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento.
@@ -212,7 +213,33 @@ local function CreateRaws( PARTS)
EgtAddPartToRawPart( PARTS[i].id, ORIG(), PARTS[i].idRaw)
end
end
---------------------------------------------------------------------
-- Allinea i pezzi in base a come devono essere disposti sulla tavola
---------------------------------------------------------------------
-- TODO in questa fase bisogna già sapere qual è la prima fase e posizionare il pezzo di conseguenza
-- TODO (bassa priorità) adesso allinea sempre in X, ma bisognerebbe farlo in base ad un parametro in WINDATA che dice come si dispongono in macchina
local function AlignRawsToTable( PARTS)
for i = 1, #PARTS do
-- allineo il pezzo all'interno del grezzo
local dRotX, dRotY, dRotZ = GetFixedAxesRotABCFromFrame( PARTS[i].frame)
-- se devo ruotare
if dRotZ ~= 0 then
EgtRotatePartInRawPart( PARTS[i].id, Z_AX(), -dRotZ)
-- sposto punto in basso a sinistra del pezzo sul punto in basso a sinistra del grezzo
local dPartPosX = EgtGetBBoxGlob( PARTS[i].id, GDB_BB.STANDARD):getMin():getX()
local dPartPosY = EgtGetBBoxGlob( PARTS[i].id, GDB_BB.STANDARD):getMin():getY()
local dRawPosX = EgtGetRawPartBBox( PARTS[i].idRaw):getMin():getX()
local dRawPosY = EgtGetRawPartBBox( PARTS[i].idRaw):getMin():getY()
local vtMove = Vector3d( dRawPosX - dPartPosX, dRawPosY - dPartPosY, 0)
EgtMovePartInRawPart( PARTS[i].id, vtMove)
end
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Funzione per trovare nome MachGroup ***
-------------------------------------------------------------------------------------------------------------
@@ -244,7 +271,7 @@ local function MyProcessPieces()
CreateRaws( PARTS)
-- allineo i pezzi come orientamento richiesto dalla macchina
WinData.AlignRawsToTable( PARTS)
AlignRawsToTable( PARTS)
-- aggiungo sovramateriale ai grezzi
AddOverMaterialToRaw( PARTS)
@@ -267,7 +294,7 @@ local function MyProcessPieces()
end
-- si dispongono i pezzi sulla tavola
WinData.Disposition( PARTS)
WinData.ExecDisposition( PARTS)
return true
end
@@ -276,7 +303,7 @@ end
-- *** Inserimento delle lavorazioni ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures()
--local bOk = WinExec.ProcessFeatures( PARTS)
local bOk = WinExec.ProcessFeatures( PARTS)
return true
end
+17
View File
@@ -0,0 +1,17 @@
-- Cutting.lua by Egalware s.r.l. 2024/06/13
-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di taglio
-- Tabella per definizione modulo
local Cutting = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
EgtOutLog( ' Cutting started', 1)
EgtMdbSave()
-------------------------------------------------------------------------------------------------------------
return Cutting
+17
View File
@@ -0,0 +1,17 @@
-- Drilling.lua by Egalware s.r.l. 2024/06/13
-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di foratura
-- Tabella per definizione modulo
local Drilling = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
EgtOutLog( ' Drilling started', 1)
EgtMdbSave()
-------------------------------------------------------------------------------------------------------------
return Drilling
+17
View File
@@ -0,0 +1,17 @@
-- Milling.lua by Egalware s.r.l. 2024/06/13
-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di fresatura
-- Tabella per definizione modulo
local Milling = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
EgtOutLog( ' Milling started', 1)
EgtMdbSave()
-------------------------------------------------------------------------------------------------------------
return Milling
+17
View File
@@ -0,0 +1,17 @@
-- Pocketing.lua by Egalware s.r.l. 2024/06/13
-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di svuotatura
-- Tabella per definizione modulo
local Pocketing = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
EgtOutLog( ' Pocketing started', 1)
EgtMdbSave()
-------------------------------------------------------------------------------------------------------------
return Pocketing
+38
View File
@@ -0,0 +1,38 @@
-- Profiling.lua by Egalware s.r.l. 2024/06/13
-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di profilatura
-- Tabella per definizione modulo
local Profiling = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local WinData = require( 'WinData')
EgtOutLog( ' Profiling started', 1)
EgtMdbSave()
-------------------------------------------------------------------------------------------------------------
function Profiling.Make( Proc, Part)
local Machining = {}
Machining.LeadIn = {}
Machining.LeadOut = {}
Machining.Steps = {}
Machining.sDepth = 0
Machining.dRadialOffset = Proc.dRadialOffset
Machining.dLongitudinalOffset = Proc.dLongitudinalOffset
Machining.Steps.dSideStep = TOOLS[nIndexTool].dSideStep
Machining.LeadIn.nType = MCH_MILL_LI.TANGENT
Machining.LeadIn.dTangentDistance = TOOLS[nIndexTool].dDiameter
Machining.LeadIn.dPerpDistance = TOOLS[nIndexTool].dDiameter
Machining.LeadOut.nType = MCH_MILL_LI.TANGENT
Machining.LeadOut.dTangentDistance = TOOLS[nIndexTool].dDiameter
Machining.LeadOut.dPerpDistance = 0
end
-------------------------------------------------------------------------------------------------------------
return Profiling