- 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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user