diff --git a/LuaLibs/EgtGunstockBase.lua b/LuaLibs/EgtGunstockBase.lua
new file mode 100644
index 0000000..fe86a91
--- /dev/null
+++ b/LuaLibs/EgtGunstockBase.lua
@@ -0,0 +1,462 @@
+-- EgtGunstockBase.lua by EgalTech s.r.l. 2016/09/29
+-- Gunstock Base library
+
+require( 'EgtBase')
+require( 'EgtConst')
+
+-- Tavola per definizione modulo
+local EGB = {}
+
+print( 'EgtGunstockBase started')
+
+-----------------------------------------------------------------
+-- *** MOD file scanning ***
+-----------------------------------------------------------------
+local g_fh = nil
+local g_nLine = 0
+local g_sUnLine = nil
+local g_sLastRem = nil
+
+-----------------------------------------------------------------
+function EGB.OpenFile( sFile)
+ g_fh = io.open( sFile)
+ g_nLine = 0
+ g_sUnLine = nil
+ g_sLastRem = nil
+ return g_fh
+end
+
+-----------------------------------------------------------------
+function EGB.CloseFile()
+ if not g_fh then return false end
+ g_fh:close()
+ g_fh = nil
+ g_sUnLine = nil
+ g_sLastRem = nil
+ return true
+end
+
+-----------------------------------------------------------------
+function EGB.GetLine()
+ -- verifico apertura file
+ if not g_fh then return '' end
+ -- se c'è linea rifiutata
+ if g_sUnLine then
+ local sLine = g_sUnLine
+ g_sUnLine = nil
+ return sLine
+ end
+ -- altrimenti cerco una nuova linea
+ while true do
+ -- leggo la prossima linea
+ local sLine = g_fh:read( '*l')
+ g_nLine = g_nLine + 1
+ -- se non esiste, esco
+ if not sLine then return nil end
+ -- elimino spazi iniziali e finali (compresi tab e simili)
+ sLine = EgtTrim( sLine)
+ -- se linea contiene qualcosa
+ if sLine:len() > 0 then
+ -- se non c'è comando è tutto commento
+ local nI = sLine:find( '#', 1, true)
+ if nI == 1 then
+ -- elimino eventuali commenti finali
+ local nJ = sLine:find( ';', 1, true)
+ if nJ then
+ sLine = sLine:sub( 1, nJ-1)
+ end
+ return sLine
+ -- salvo commento
+ else
+ g_sLastRem = EgtTrim( sLine:gsub( ';', ''))
+ end
+ end
+ end
+end
+
+-----------------------------------------------------------------
+function EGB.GetLineNumber()
+ return g_nLine
+end
+
+-----------------------------------------------------------------
+function EGB.UngetLine( sLine)
+ g_sUnLine = sLine
+end
+
+-----------------------------------------------------------------
+function EGB.GetLastRem()
+ return g_sLastRem
+end
+
+-----------------------------------------------------------------
+-- *** CNC file writing ***
+-----------------------------------------------------------------
+local g_wfh = nil
+
+-----------------------------------------------------------------
+function EGB.OpenOutFile( sFile)
+ g_wfh = io.open( sFile, "w")
+ return g_wfh
+end
+
+-----------------------------------------------------------------
+function EGB.CloseOutFile()
+ if not g_wfh then return false end
+ g_wfh:close()
+ g_wfh = nil
+ return true
+end
+
+-----------------------------------------------------------------
+function EGB.WriteOutLine( sLine)
+ -- verifico apertura file
+ if not g_wfh then return false end
+ g_wfh:write( sLine .. '\n')
+end
+
+-----------------------------------------------------------------
+-- *** ERR file writing ***
+-----------------------------------------------------------------
+local g_efh = nil
+
+-----------------------------------------------------------------
+function EGB.OpenErrFile( sFile)
+ g_efh = io.open( sFile, "w")
+ return g_efh
+end
+
+-----------------------------------------------------------------
+function EGB.CloseErrFile()
+ if not g_efh then return false end
+ g_efh:close()
+ g_efh = nil
+ return true
+end
+
+-----------------------------------------------------------------
+function EGB.WriteErrLine( sLine, bContinue)
+ -- eseguo log
+ EgtOutLog( sLine)
+ -- verifico apertura file
+ if not g_efh then return false end
+ g_efh:write( sLine .. '\n')
+ -- se non richiesta continuazione
+ if not bContinue then
+ EGB.CloseErrFile()
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+-- *** Machine Calc ***
+-----------------------------------------------------------------
+local function GetNearestAng( dAng, dRefAng)
+ while dAng >= dRefAng + 180 do
+ dAng = dAng - 360
+ end
+ while dAng < dRefAng - 180 do
+ dAng = dAng + 360
+ end
+ return dAng
+end
+
+-----------------------------------------------------------------
+function EGB.GetAngMach( vtTool, dNearAngR1, dNearAngR2)
+ -- calcolo angoli
+ local bOk, nStat, dAngR1A, dAngR2A, dAngR1B, dAngR2B = EgtGetCalcAngles( vtTool)
+ -- errore
+ if not bOk or nStat == 0 then return false end
+ -- angolo indeterminato
+ if nStat < 0 then
+ dAngR1A = dNearAngR1
+ end
+ -- una soluzione (anche indeterminata)
+ if abs( nStat) == 1 then
+ dAngR1A = GetNearestAng( dAngR1A, dNearAngR1)
+ dAngR2A = GetNearestAng( dAngR2A, dNearAngR2)
+ -- due soluzioni (sempre determinate)
+ elseif abs( nStat) == 2 then
+ dAngR1A = GetNearestAng( dAngR1A, dNearAngR1)
+ dAngR2A = GetNearestAng( dAngR2A, dNearAngR2)
+ dAngR1B = GetNearestAng( dAngR1B, dNearAngR1)
+ dAngR2B = GetNearestAng( dAngR2B, dNearAngR2)
+ local dDeltaA = abs( dAngR1A - dNearAngR1) --+ abs( dAngR2A - dNearAngR2)
+ local dDeltaB = abs( dAngR1B - dNearAngR1) --+ abs( dAngR2B - dNearAngR2)
+ if dDeltaB < dDeltaA - GEO.EPS_ANG_SMALL then
+ dAngR1A, dAngR1B = dAngR1B, dAngR1A
+ dAngR2A, dAngR2B = dAngR2B, dAngR2A
+ end
+ end
+ return true, dAngR1A, dAngR2A
+end
+
+-----------------------------------------------------------------
+-- *** Import Cnc ***
+-----------------------------------------------------------------
+local function ConvertLine( sLine, vSubst, bAddM6ToT3x)
+ local sNew = ''
+ -- Se necessario, analisi e conversione linea
+ local sStL = sLine:sub( 1, 1)
+ if sStL ~= '(' and sStL ~= ';' and sStL ~= '"' and sStL ~= '$' then
+ local vTok = EgtSplitStringPlus( sLine, 'NGXYZIJKRUVWABCFTMHh;')
+ local bRem = false
+ for i = 1, #vTok do
+ local sTok = vTok[i]
+ local sStT = sTok:sub( 1, 1)
+ if ( #sTok >= 2 and not bRem and
+ ( sStT == 'X' or sStT == 'Y' or sStT == 'Z' or sStT == 'h')) then
+ local sVal = sTok:sub( 2)
+ -- sostituzione variabili con loro valori
+ if vSubst then
+ for j = #vSubst, 1, -1 do
+ local Subst = vSubst[j]
+ sVal = sVal:gsub( Subst[1], Subst[2])
+ end
+ end
+ sVal = EgtTrim( sVal)
+ if sVal == '' then sVal = '0' end
+ -- valutazione espressione
+ local dVal = EgtEvalNumExpr( sVal)
+ -- assegnazione risultato
+ if dVal then
+ sNew = sNew .. sStT .. EgtNumToString( dVal, 6)
+ else
+ sNew = sNew .. sStT .. '0'
+ end
+ if sTok:sub( -1, -1) == ' ' then
+ sNew = sNew .. ' '
+ end
+ elseif ( #sTok >= 2 and not bRem and sStT == 'T') then
+ local sVal = sTok:sub( 2)
+ local nVal = tonumber( sVal)
+ -- se richiesto, aggiungere M6 alle posizioni maggiori di 30
+ if bAddM6ToT3x and nVal and nVal > 30 then
+ sNew = sNew .. sTok .. ' M6'
+ else
+ sNew = sNew .. sTok
+ end
+ else
+ sNew = sNew .. sTok
+ if sStT == ';' then bRem = true end
+ end
+ end
+ -- lettura valore parametro E10
+ if sNew:sub( 1, 4) == 'E10=' then
+ local sVal = sNew:sub(5)
+ if sVal then
+ table.insert( vSubst, 3, {'E10', sVal})
+ end
+ end
+ elseif sLine:sub( 1, 5) == '(UIO,' then
+ sNew = 'G59 ' .. sLine:sub( 6, -2)
+ else
+ sNew = sLine
+ end
+ return sNew
+end
+
+-----------------------------------------------------------------
+local function ConvertSubToCnc( sSubFile, sCncFile, vSubst, bAddM6ToT3x)
+ --EgtOutLog( 'ConvertSubToCnc ' .. sSubFile)
+ -- Apro file Sub in lettura
+ local fhSub = io.open( sSubFile)
+ if not fhSub then
+ EgtOutLog( 'Error opening file ' .. sSubFile)
+ return false
+ end
+ -- leggo file Sub in un array di linee
+ local vLine = {}
+ while true do
+ local sLine = fhSub:read( '*l')
+ if not sLine then break end
+ table.insert( vLine, EgtTrim( sLine))
+ end
+ -- chiudo file Sub
+ fhSub:close()
+
+ -- Reset conversione E10
+ if vSubst then
+ if vSubst[3][1] == 'E10' then
+ table.remove( vSubst, 3)
+ end
+ end
+
+ -- Apro file CNC in scrittura
+ local fhCnc = io.open( sCncFile, 'w')
+ if not fhCnc then
+ fhSub:close()
+ EgtOutLog( 'Error opening file ' .. sCncFile)
+ return false
+ end
+ -- Ciclo di conversione
+ local nRpt = 0
+ local vRpt = {}
+ for i = 1, #vLine do
+ local sLine = vLine[i]
+ -- Se richiesto inserimento altre linee
+ if sLine:find( '(EPP,', 1, true) == 1 then
+ -- Recupero gli estremi dell'intervallo da inserire
+ sLine = sLine:gsub( '%(EPP,', '')
+ sLine = sLine:gsub( '%)', '')
+ local vsTok = EgtSplitString( sLine, ',')
+ local sStart = vsTok[1]
+ local sEnd = vsTok[2]
+ -- Recupero le linee da inserire
+ --EgtOutLog( 'Start=' .. ( sStart or '') .. ' End=' .. ( sEnd or ''))
+ if sStart and sEnd then
+ local bCopy = false
+ for j = 1, #vLine do
+ local sTemp = vLine[j]
+ if sTemp:find( '"'..sStart, 1, true) == 1 then
+ bCopy = true
+ elseif sTemp:find( '"'..sEnd, 1, true) == 1 then
+ bCopy = false
+ elseif bCopy then
+ -- Conversione linea
+ local sNew = ConvertLine( sTemp, vSubst, bAddM6ToT3x)
+ -- Scrittura nuova linea
+ fhCnc:write( sNew .. '\n')
+ end
+ end
+ end
+ -- se inizio ripetizione
+ elseif sLine:find( '(RPT,', 1, true) == 1 then
+ -- Lettura numero ripetizioni e inizialzzazioni
+ local sVal = sLine:gsub( '%(RPT,', '')
+ sVal = sVal:gsub( '%)', '')
+ nRpt = tonumber( sVal)
+ vRpt = {}
+ -- Conversione e scrittura linea
+ local sNew = ConvertLine( sLine, vSubst, bAddM6ToT3x)
+ fhCnc:write( sNew .. '\n')
+ -- se fine ripetizione
+ elseif sLine:find( '(ERP', 1, true) == 1 then
+ -- Inserisco le linee da ripetere
+ for j = 1, nRpt - 1 do
+ for k = 1, #vRpt do
+ -- Conversione e scrittura linea
+ local sNew = ConvertLine( vRpt[k], vSubst, bAddM6ToT3x)
+ fhCnc:write( sNew .. '\n')
+ end
+ end
+ -- reset ripetizioni
+ nRpt = 0
+ vRpt = {}
+ -- Conversione e scrittura linea
+ local sNew = ConvertLine( sLine, vSubst, bAddM6ToT3x)
+ fhCnc:write( sNew .. '\n')
+ -- altrimenti linea standard
+ else
+ -- Se in gruppo da ripetere, salvo la linea
+ if nRpt > 1 then table.insert( vRpt, sLine) end
+ -- Conversione linea
+ local sNew = ConvertLine( sLine, vSubst, bAddM6ToT3x)
+ -- Scrittura nuova linea
+ fhCnc:write( sNew .. '\n')
+ end
+ end
+ -- Chiudo file CNC
+ fhCnc:close()
+
+ -- Ritorno con successo
+ return true
+end
+
+-----------------------------------------------------------------
+local function ConvertCncToNge( sCncFile, sNgeFile)
+ --EgtOutLog( 'ConvertCncToNge ' .. sCncFile)
+ -- Creazione contesto geometrico per importazione
+ local nCurrCtx = EgtGetContext()
+ local nCtx = EgtCreateContext()
+ if not nCtx then
+ EgtLogOut( 'Error in CreateContext')
+ return false
+ end
+ -- Esecuzione importazione
+ if not EgtImportCnc( sCncFile, EIC_FL.CHAIN + EIC_FL.SKIP_ZEROMACH + EIC_FL.SKIP_RAPID) then
+ EgtLogOut( 'Error in ImportCnc')
+ return false
+ end
+ -- Salvataggio in formato Nge
+ if not EgtSaveFile( sNgeFile, GDB_NT.BIN) then
+ EgtLogOut( 'Error in SaveFile')
+ return false
+ end
+ -- Cancellazione contesto geometrico per importazione e ripristino contesto originale
+ EgtSetContext( nCurrCtx)
+ EgtDeleteContext( nCtx)
+ -- Ritorno con successo
+ return true
+end
+
+-----------------------------------------------------------------
+local function InsertInLayer( sNgeFile, nLayId)
+ -- Inserimento file
+ if not EgtInsertFile( sNgeFile) then
+ EgtLogOut( 'Error in InsertFile')
+ return false
+ end
+ -- Spostamento entità geometriche nel layer destinazione
+ local nPz = EgtGetLastPart()
+ local nLay = EgtGetFirstLayer( nPz)
+ -- cerco layer con nome valido (tipo TCPOS)
+ local sName = EgtGetName( nLay or GDB_ID.NULL)
+ if not sName or sName == 'T00' then
+ local nNextLay = EgtGetNextLayer( nLay or GDB_ID.NULL)
+ local sNextName = EgtGetName( nNextLay or GDB_ID.NULL)
+ if sNextName and sNextName ~= 'T00' then
+ nLay = nNextLay
+ end
+ end
+ local nId = EgtGetFirstInGroup( nLay or GDB_ID.NULL)
+ while nId do
+ -- sposto
+ EgtRelocate( nId, nLayId)
+ -- recupero correttore e lo metto nel layer
+ local sTcomp = EgtGetInfo( nId, 'TCOMP')
+ if sTcomp then
+ EgtSetInfo( nLayId, 'TCOMP', sTcomp)
+ end
+ -- passo al successivo
+ nId = EgtGetFirstInGroup( nLay)
+ end
+ -- Copia nome come info di posizione cambio utensile
+ local sTcPos = EgtGetName( nLay or GDB_ID.NULL)
+ if sTcPos then
+ EgtSetInfo( nLayId, 'TCPOS', sTcPos)
+ end
+ -- Copia eventuale info con nome di utensile
+ local sToolName = EgtGetInfo( nLay or GDB_ID.NULL, 'TNAME')
+ if sToolName then
+ EgtSetInfo( nLayId, 'TNAME', sToolName)
+ end
+ -- Cancello pezzo di inserimento
+ EgtErase( nPz or GDB_ID.NULL)
+ -- Ritorno con successo
+ return ( nPz ~= nil)
+end
+
+-----------------------------------------------------------------
+function EGB.ImportCnc( sDir, sTmpDir, sName, vSubst, bAddM6ToT3x, nLayId)
+ local sSubFile = sDir .. sName
+ local sCncFile = sTmpDir .. sName .. '.cnc'
+ local sNgeFile = sTmpDir .. sName .. '.nge'
+ -- Converto file Iso parametrico in numerico
+ if not ConvertSubToCnc( sSubFile, sCncFile, vSubst, bAddM6ToT3x) then
+ return false
+ end
+ -- Converto in file Nge
+ if not ConvertCncToNge( sCncFile, sNgeFile) then
+ return false
+ end
+ -- Inserisco nel giusto layer del pezzo
+ if not InsertInLayer( sNgeFile, nLayId) then
+ return false
+ end
+ -- Ritorno con successo
+ return true
+end
+
+
+return EGB
diff --git a/Main.lua b/Main.lua
new file mode 100644
index 0000000..3fdb6b4
--- /dev/null
+++ b/Main.lua
@@ -0,0 +1,1236 @@
+-- Main.lua by Egaltech s.r.l. 2016/10/18
+-- Main gestione lavorazioni Gunstock
+
+-- Intestazioni
+require( 'EgtBase')
+_ENV = EgtProtectGlobal()
+EgtEnableDebug( false)
+
+local sBaseDir = EgtGetSourceDir()
+EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua')
+EGB = require( 'EgtGunstockBase')
+
+-----------------------------------------------------------------
+-- *** Global Variables ***
+-----------------------------------------------------------------
+_G.GGD = {}
+
+-----------------------------------------------------------------
+-- *** Local Variables ***
+-----------------------------------------------------------------
+local m_sModName
+local m_sMachName
+local m_sAttr
+local m_sSboName
+local m_vParams = {} -- array di record : .sName, .dMin, .dMax, .dDef, .sVar
+local m_vVals = {} -- array di valori dei parametri da file PEZ
+local m_vVars = {}
+local m_vRaw = {}
+local m_vRawRef = {}
+local m_vGunRef = {}
+local m_vMachs = {} -- array di record : .sInfo, .sName, .nLay, .Ang, .PrepRot, [1]...[N] Tras o Rotaz
+local m_dCoeffAlt = 1 -- coefficiente altezza per posizionamento due pezzi uno sopra l'altro
+local m_vSboMove = {} -- parametri di movimento sbozzato : X, Y, R
+
+-----------------------------------------------------------------
+-- *** Local Constants ***
+-----------------------------------------------------------------
+local LEN_MIN_RIFLE = 650
+
+-----------------------------------------------------------------
+-- *** MOD file parsing ***
+-----------------------------------------------------------------
+local function GetHeader()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#NOME', 1, true) then return false end
+ m_sModName = EgtTrim( sLine:gsub( '#NOME', ''))
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#MACH', 1, true) then return false end
+ m_sMachName = EgtTrim( sLine:gsub( '#MACH', ''))
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#ATTR', 1, true) then
+ EGB.UngetLine( sLine)
+ m_sAttr = ''
+ else
+ m_sAttr = EgtTrim( sLine:gsub( '#ATTR', ''))
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+local function GetParams()
+ m_vParams = {}
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ -- facoltativo
+ if not sLine:find( '#PARAM', 1, true) then
+ EGB.UngetLine( sLine)
+ return true
+ end
+ while not sLine:find( '#END_PAR', 1, true) do
+ if not sLine:find( '#PARAM', 1, true) then return false end
+ local sParam = EgtTrim( sLine:gsub( '#PARAM', ''))
+ local vsTok = EgtSplitString( sParam, ' ')
+ local Param = {}
+ Param.sName = vsTok[1]
+ Param.dMin = tonumber( vsTok[2])
+ Param.dMax = tonumber( vsTok[3])
+ Param.dDef = tonumber( vsTok[4])
+ Param.sVar = vsTok[5]
+ table.insert( m_vParams, Param)
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+local function GetVars()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ while not sLine:find( '#END_VAR', 1, true) do
+ if not sLine:find( '#VAR', 1, true) then return false end
+ local sVar = EgtTrim( sLine:gsub( '#VAR', ''))
+ local vsTok = EgtSplitString( sVar, ' ')
+ local Var = {}
+ Var.sName = vsTok[1]
+ Var.sExpr = vsTok[2]
+ Var.dVal = 0
+ table.insert( m_vVars, Var)
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+local function GetRawDim()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#LUNG_GREZZO', 1, true) then return false end
+ m_vRaw.sLenExpr = EgtTrim( sLine:gsub( '#LUNG_GREZZO', ''))
+ m_vRaw.dLen = 0
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#LARG_GREZZO', 1, true) then return false end
+ m_vRaw.sLarExpr = EgtTrim( sLine:gsub( '#LARG_GREZZO', ''))
+ m_vRaw.dLar = 0
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#ALT_GREZZO', 1, true) then return false end
+ m_vRaw.sAltExpr = EgtTrim( sLine:gsub( '#ALT_GREZZO', ''))
+ m_vRaw.dAlt = 0
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#DOPPIO', 1, true) then
+ m_dCoeffAlt = 1
+ else
+ m_dCoeffAlt = EgtIf( EgtTrim( sLine:gsub( '#DOPPIO', '')) ~= '0', 2, 1)
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ if not sLine:find( '#SBO', 1, true) then
+ m_sSboName = nil
+ else
+ m_sSboName = EgtTrim( sLine:gsub( '#SBO', ''))
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ if not sLine:find( '#MUOVI_SBO', 1, true) then
+ m_vSboMove = nil
+ else
+ sLine = sLine:gsub( '#MUOVI_SBO', '')
+ sLine = sLine:gsub( 'X', '')
+ sLine = sLine:gsub( 'Y', ',')
+ sLine = sLine:gsub( 'R', ',')
+ local vsTok = EgtSplitString( sLine, ',')
+ m_vSboMove.sX = EgtTrim( vsTok[1])
+ m_vSboMove.dX = 0
+ m_vSboMove.sY = EgtTrim( vsTok[2])
+ m_vSboMove.dY = 0
+ m_vSboMove.sR = EgtTrim( vsTok[3])
+ m_vSboMove.dR = 0
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ return sLine:find( '#END_DIM_GREZZO', 1, true)
+end
+
+-----------------------------------------------------------------
+local function GetStartStdMachining()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ return sLine:find( '#LAV_PIA_', 1, true)
+end
+
+-----------------------------------------------------------------
+local function GetEndStdMachining()
+ local sLine = EGB.GetLine()
+ if not sLine then return true end
+ if sLine:find( '#END_PIA_', 1, true) then
+ return true
+ else
+ EGB.UngetLine( sLine)
+ return false
+ end
+end
+
+-----------------------------------------------------------------
+local function ParseTras( sParam)
+ local Tras = {}
+ Tras.Type = 1
+ sParam = sParam:gsub( 'X', '')
+ sParam = sParam:gsub( 'Y', ',')
+ sParam = sParam:gsub( 'Z', ',')
+ local vsTok = EgtSplitString( sParam, ',')
+ if #vsTok < 3 then return nil end
+ Tras.sXExpr = vsTok[1]
+ Tras.sYExpr = vsTok[2]
+ Tras.sZExpr = vsTok[3]
+ Tras.dX = 0
+ Tras.dY = 0
+ Tras.dZ = 0
+ return Tras
+end
+
+-----------------------------------------------------------------
+local function ParseRotaz( sParam)
+ local Rotaz = {}
+ Rotaz.Type = 2
+ local vsTok = EgtSplitString( sParam, ' ')
+ if #vsTok < 3 then return nil end
+ Rotaz.sAx = vsTok[1]
+ Rotaz.sMode = vsTok[2]
+ Rotaz.sAngExpr = vsTok[3]
+ Rotaz.dAng = 0
+ return Rotaz
+end
+
+-----------------------------------------------------------------
+local function GetRawRef()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#RIF_GRE', 1, true) then return false end
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ while not sLine:find( '#END_RIF', 1, true) do
+ if sLine:find( '#TRAS', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#TRAS', ''))
+ local Tras = ParseTras( sParam)
+ if not Tras then return false end
+ table.insert( m_vRawRef, Tras)
+ elseif sLine:find( '#ROTAZ', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#ROTAZ', ''))
+ local Rotaz = ParseRotaz( sParam)
+ if not Rotaz then return false end
+ table.insert( m_vRawRef, Rotaz)
+ else
+ return false
+ end
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+local function GetGunRef()
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#RIF_FUCILE', 1, true) then return false end
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ while not sLine:find( '#END_RIF', 1, true) do
+ if sLine:find( '#TRAS', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#TRAS', ''))
+ local Tras = ParseTras( sParam)
+ if not Tras then return false end
+ table.insert( m_vGunRef, Tras)
+ elseif sLine:find( '#ROTAZ', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#ROTAZ', ''))
+ local Rotaz = ParseRotaz( sParam)
+ if not Rotaz then return false end
+ table.insert( m_vGunRef, Rotaz)
+ else
+ return false
+ end
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ return true
+end
+
+-----------------------------------------------------------------
+local function GetMachining()
+ -- inizio lavorazione
+ local sLine = EGB.GetLine()
+ if not sLine then return false end
+ if not sLine:find( '#LAV', 1, true) then return false end
+ local vMach = {}
+ vMach.sInfo = EGB.GetLastRem()
+ vMach.sName = EgtTrim( sLine:gsub( '#LAV', ''))
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ while not sLine:find( '#END_SING_LAV', 1, true) do
+ if sLine:find( '#TRAS', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#TRAS', ''))
+ local Tras = ParseTras( sParam)
+ if not Tras then return false end
+ table.insert( vMach, Tras)
+ elseif sLine:find( '#ROTAZ', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#ROTAZ', ''))
+ local Rotaz = ParseRotaz( sParam)
+ if not Rotaz then return false end
+ table.insert( vMach, Rotaz)
+ elseif sLine:find( '#ANG', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#ANG', ''))
+ local vsTok = EgtSplitString( sParam, ' ')
+ if #vsTok < 2 then return false end
+ local Ang = {}
+ Ang.sR1Expr = vsTok[1]
+ Ang.dR1 = 0
+ Ang.sR2Expr = vsTok[2]
+ Ang.dR2 = 0
+ vMach.Ang = Ang
+ elseif sLine:find( '#TESTA_USCITA', 1, true) then
+ --
+ elseif sLine:find( '#PREP_ROT', 1, true) then
+ local sParam = EgtTrim( sLine:gsub( '#PREP_ROT', ''))
+ local vsTok = EgtSplitString( sParam, ' ')
+ if #vsTok < 2 then return false end
+ local PrepRot = {}
+ PrepRot.sR1Expr = vsTok[1]
+ PrepRot.dR1 = 0
+ PrepRot.sR2Expr = vsTok[2]
+ PrepRot.dR2 = 0
+ PrepRot.sFeedExpr = vsTok[3]
+ PrepRot.dFeed = 0
+ vMach.PrepRot = PrepRot
+ else
+ return false
+ end
+ sLine = EGB.GetLine()
+ if not sLine then return false end
+ end
+ table.insert( m_vMachs, vMach)
+ return true
+end
+
+-----------------------------------------------------------------
+-- *** Evaluate MOD expression ***
+-----------------------------------------------------------------
+local function AdjustFunction( sTmp, sOri, sNewS, sNewE)
+ local nEnd = sTmp:find( sOri, 1, true)
+ while nEnd do
+ -- ricerca corrispondente parentesi aperta
+ local nSta = nEnd - 1
+ local nCount = 1
+ while sTmp:sub(nSta,nSta) ~= '(' or nCount > 1 do
+ if sTmp:sub(nSta,nSta) == ')' then
+ nCount = nCount + 1
+ elseif sTmp:sub(nSta,nSta) == '(' then
+ nCount = nCount - 1
+ end
+ nSta = nSta - 1
+ if nSta == 0 then
+ return nil
+ end
+ end
+ -- sostituzioni
+ sTmp = sTmp:sub( 1, nEnd - 1) .. sNewE .. sTmp:sub( nEnd + sOri:len())
+ sTmp = sTmp:sub( 1, nSta - 1) .. sNewS .. sTmp:sub( nSta + 1)
+ -- nuova ricerca
+ nEnd = sTmp:find( sOri, 1, true)
+ end
+ return sTmp
+end
+
+-----------------------------------------------------------------
+local function EvaluateExpr( sExpr)
+ local sTmp = sExpr or ''
+ -- sostituzione valori dei parametri
+ for i = 1, #m_vParams do
+ local Param = m_vParams[i]
+ if Param.dVal >= 0 then
+ sTmp = sTmp:gsub( '@'..Param.sName, EgtNumToString( Param.dVal, 3))
+ else
+ sTmp = sTmp:gsub( '@'..Param.sName, '('..EgtNumToString( Param.dVal, 3)..')')
+ end
+ end
+ -- sostituzione valori delle variabili
+ for i = 1, #m_vVars do
+ local Var = m_vVars[i]
+ if Var.dVal >= 0 then
+ sTmp = sTmp:gsub( '@'..Var.sName, EgtNumToString( Var.dVal, 3))
+ else
+ sTmp = sTmp:gsub( '@'..Var.sName, '('..EgtNumToString( Var.dVal, 3)..')')
+ end
+ end
+ -- sostituzione costanti
+ sTmp = sTmp:gsub( 'P', 'pi')
+ -- sistemazione funzioni
+ sTmp = AdjustFunction( sTmp, ')Q', 'pow(', ',2)')
+ sTmp = AdjustFunction( sTmp, ')R', 'sqrt(', ')')
+ sTmp = AdjustFunction( sTmp, ')S', 'sin(', ')')
+ sTmp = AdjustFunction( sTmp, ')C', 'cos(', ')')
+ sTmp = AdjustFunction( sTmp, ')T', 'tan(', ')')
+ sTmp = AdjustFunction( sTmp, ')AS', 'asin(', ')')
+ sTmp = AdjustFunction( sTmp, ')AC', 'acos(', ')')
+ sTmp = AdjustFunction( sTmp, ')AT', 'atan(', ')')
+ -- valutazione espressione
+ return EgtEvalNumExpr( sTmp)
+end
+
+-----------------------------------------------------------------
+local function EvaluateVars()
+ for i = 1, #m_vVars do
+ local Var = m_vVars[i]
+ Var.dVal = EvaluateExpr( Var.sExpr)
+ if not Var.dVal then
+ EGB.WriteErrLine( 'ERR=106\nErrore nella valutazione della variabile '.. Var.sName)
+ GGD.ERR = 106
+ return
+ end
+ end
+ for i = 1, #m_vVars do
+ local Var = m_vVars[i]
+ EgtOutLog( 'Var = ' .. Var.sName .. ' ' .. Var.sExpr .. ' -> ' .. EgtNumToString( Var.dVal, 3))
+ end
+end
+
+-----------------------------------------------------------------
+local function EvaluateRawDim()
+ m_vRaw.dLen = EvaluateExpr( m_vRaw.sLenExpr)
+ m_vRaw.dLar = EvaluateExpr( m_vRaw.sLarExpr)
+ m_vRaw.dAlt = EvaluateExpr( m_vRaw.sAltExpr)
+ if not m_vRaw.dLen or not m_vRaw.dLar or not m_vRaw.dAlt then
+ EGB.WriteErrLine( 'ERR=108\nErrore nella valutazione delle dimensioni del grezzo')
+ GGD.ERR = 108
+ return
+ end
+ EgtOutLog( 'RawLen = ' .. m_vRaw.sLenExpr .. ' -> ' .. EgtNumToString( m_vRaw.dLen, 3))
+ EgtOutLog( 'RawLar = ' .. m_vRaw.sLarExpr .. ' -> ' .. EgtNumToString( m_vRaw.dLar, 3))
+ EgtOutLog( 'RawAlt = ' .. m_vRaw.sAltExpr .. ' -> ' .. EgtNumToString( m_vRaw.dAlt, 3))
+ if m_vSboMove then
+ m_vSboMove.dX = EvaluateExpr( m_vSboMove.sX)
+ m_vSboMove.dY = EvaluateExpr( m_vSboMove.sY)
+ m_vSboMove.dR = EvaluateExpr( m_vSboMove.sR)
+ EgtOutLog( 'MoveSbo X = ' .. m_vSboMove.sX .. ' -> ' .. EgtNumToString( m_vSboMove.dX, 3))
+ EgtOutLog( 'MoveSbo Y = ' .. m_vSboMove.sY .. ' -> ' .. EgtNumToString( m_vSboMove.dY, 3))
+ EgtOutLog( 'MoveSbo R = ' .. m_vSboMove.sR .. ' -> ' .. EgtNumToString( m_vSboMove.dR, 3))
+ end
+end
+
+-----------------------------------------------------------------
+local function WriteOutLineFromIni( sSec, sKey, sDef, sIniFile)
+ local sLine = EgtGetStringFromIni( sSec, sKey, sDef, sIniFile)
+ if #sLine == 0 then return end
+ EGB.WriteOutLine( sLine:gsub( '
', '\n'))
+end
+
+
+-----------------------------------------------------------------
+-- *** Read MOD params ***
+-----------------------------------------------------------------
+function GGD.ReadModParams()
+ -- Path completa file MOD
+ local sModFile = GGD.MODFILE
+
+ -- Apertura file MOD
+ if not EGB.OpenFile( sModFile) then
+ EgtOutLog( 'ERR=102\nErrore nell\'apertura del file ' .. sModFile)
+ GGD.ERR = 102
+ return
+ end
+
+ -- Recupero header modello
+ if not GetHeader() then
+ EgtOutLog( 'ERR=103\nErrore in lettura NOME o MACH')
+ GGD.ERR = 103
+ return
+ end
+ GGD.MODNAME = m_sModName
+ EgtOutLog( 'Name = ' .. m_sModName .. ' Mach = ' .. m_sMachName .. ' Attr = ' .. m_sAttr)
+
+ -- Recupero parametri (opzionali)
+ if not GetParams() then
+ EgtOutLog( 'ERR=104\nErrore in lettura PARAM')
+ GGD.ERR = 104
+ return
+ end
+ GGD.PARTOT = #m_vParams
+ for i = 1, #m_vParams do
+ local Param = m_vParams[i]
+ EgtOutLog( 'Param = '..Param.sName..' '..EgtNumToString( Param.dMin, 1)..' '..EgtNumToString( Param.dMax, 1)..
+ ' '..EgtNumToString( Param.dDef, 1) .. ' ' .. Param.sVar)
+ local sParNameI = 'PARNAME' .. tostring(i)
+ GGD[sParNameI] = Param.sName
+ local sParMinI = 'PARMIN' .. tostring(i)
+ GGD[sParMinI] = Param.dMin
+ local sParMaxI = 'PARMAX' .. tostring(i)
+ GGD[sParMaxI] = Param.dMax
+ local sParDefI = 'PARDEF' .. tostring(i)
+ GGD[sParDefI] = Param.dDef
+ local sParVarI = 'PARVAR' .. tostring(i)
+ GGD[sParVarI] = Param.sVar
+ end
+ for i = 1, #m_vParams do
+ local Param = m_vParams[i]
+ Param.dVal = Param.dDef
+ end
+
+ -- Recupero variabili (come espressioni)
+ if not GetVars() then
+ EGB.WriteErrLine( 'ERR=105\nErrore in lettura VAR')
+ GGD.ERR = 105
+ return
+ end
+
+ -- Recupero dimensioni grezzo (come espressioni)
+ if not GetRawDim() then
+ EGB.WriteErrLine( 'ERR=107\nErrore in lettura DIM_GREZZO')
+ GGD.ERR = 107
+ return
+ end
+
+ -- Chiusura file MOD
+ EGB.CloseFile()
+
+ GGD.ERR = 0
+end
+
+-----------------------------------------------------------------
+-- *** Read PEZ params ***
+-----------------------------------------------------------------
+function GGD.ReadPezParams()
+ -- Path completa file PEZ
+ local sPezFile = GGD.PEZFILE
+
+ -- Direttorio del modello
+ local sPezDir = EgtSplitPath( sPezFile)
+ local sModDir = sPezDir:sub( 1, -5) .. 'MOD\\'
+ --EgtOutLog( 'ModDir='..sModDir)
+
+ -- Apertura file PEZ
+ local PezFh = io.open( sPezFile, 'r')
+ if not PezFh then
+ EgtOutLog( 'ERR=117\nErrore nell\'apertura del file ' .. sPezFile)
+ GGD.ERR = 117
+ return
+ end
+
+ -- Lettura parametri generali
+ local sLine = PezFh:read( '*l')
+ -- identificativo, non interessa
+ sLine = PezFh:read( '*l')
+ if sLine then
+ GGD.DESCR = EgtTrim( sLine:gsub( 'Descrizione :', '') or '')
+ end
+ sLine = PezFh:read( '*l')
+ if sLine then
+ local sModFile = EgtTrim( sLine:gsub( 'Modello :', '' ) or '')
+ local _, sModName, sModExt = EgtSplitPath( sModFile)
+ GGD.MODFILE = sModDir .. sModName .. sModExt
+ else
+ EgtOutLog( 'ERR=118\nErrore nella lettura del nome del modello da ' .. sPezFile)
+ GGD.ERR = 118
+ return
+ end
+ sLine = PezFh:read( '*l')
+ if sLine then
+ GGD.DIMGREZ = EgtTrim( sLine:gsub( 'Dim. Grezzo :', '' ) or '')
+ end
+
+ -- Lettura parametri modello
+ GGD.ReadModParams()
+ if GGD.ERR ~= 0 then
+ return
+ end
+
+ -- Continuo lettura parametri generici pezzo
+ for i = 1, #m_vParams do
+ sLine = PezFh:read( '*l')
+ if sLine then
+ local sVal = EgtTrim( sLine:gsub( m_vParams[i].sName .. ' :', '' ) or '')
+ m_vParams[i].dVal = tonumber( sVal)
+ end
+ end
+
+ -- Chiusura file PEZ
+ PezFh:close()
+
+ -- Assegno valori letti
+ for i = 1, #m_vParams do
+ local sParValI = 'PARVAL' .. tostring(i)
+ GGD[sParValI] = m_vParams[i].dVal
+ end
+
+ GGD.ERR = 0
+end
+
+-----------------------------------------------------------------
+-- *** Write PEZ params ***
+-----------------------------------------------------------------
+function GGD.WritePezParams()
+
+ -- Assegnazione parametri
+ for i = 1, #m_vParams do
+ local sParValI = 'PARVAL' .. tostring(i)
+ m_vParams[i].dVal = GGD[sParValI]
+ m_vVals[i] = m_vParams[i].dVal
+ end
+
+ -- Valutazione variabili
+ EvaluateVars()
+ if GGD.ERR ~= 0 then
+ return
+ end
+
+ -- Valutazione dimensioni grezzo
+ EvaluateRawDim()
+ if GGD.ERR ~= 0 then
+ return
+ end
+ GGD.DIMGREZ = EgtNumToString( m_vRaw.dLen, 3) .. ' x ' ..
+ EgtNumToString( m_vRaw.dLar, 3) .. ' x ' ..
+ EgtNumToString( m_vRaw.dAlt, 3)
+
+ -- Path completa file PEZ
+ local sPezFile = GGD.PEZFILE
+ local sPezDir, sPezName, sPezExt = EgtSplitPath( sPezFile)
+
+ -- Apertura file PEZ
+ local PezFh = io.open( sPezFile, 'w')
+ if not PezFh then
+ EgtOutLog( 'ERR=116\nErrore nell\'apertura del file ' .. sPezFile)
+ GGD.ERR = 116
+ return
+ end
+
+ -- Scrittura parametri
+ PezFh:write( 'Identificativo : ' .. sPezName .. '\n')
+ PezFh:write( 'Descrizione : ' .. GGD.DESCR .. '\n')
+ PezFh:write( 'Modello : ' .. GGD.MODFILE .. '\n')
+ PezFh:write( 'Dim. Grezzo : ' .. GGD.DIMGREZ .. '\n')
+ for i = 1, #m_vParams do
+ PezFh:write( m_vParams[i].sName .. ' : ' .. EgtNumToString( m_vParams[i].dVal, 3) .. '\n')
+ end
+
+ -- Chiusura file PEZ
+ PezFh:close()
+
+ GGD.ERR = 0
+end
+
+-----------------------------------------------------------------
+-- *** GUNSTOCK creation with MOD parse ***
+-----------------------------------------------------------------
+function GGD.CreateGunstock()
+ local bOk = true
+ local sModFile = GGD.MODFILE
+ local sPezFile = GGD.PEZFILE
+ local sModDir, sModName, sModExt = EgtSplitPath( sModFile)
+ local sPezDir, sPezName, sPezExt = EgtSplitPath( sPezFile)
+ local sBaseDir = sPezDir:sub( 1, -5)
+ local sSboDir = sBaseDir .. 'SBO\\'
+ local sSubDir = sBaseDir .. 'SUB\\'
+ local sTmpDir = sBaseDir .. 'TMP\\'
+ local sErrFile = sPezDir .. sPezName .. '.txt'
+ local sCncFile = sBaseDir .. 'CNC\\' .. sPezName
+ local sNgeFile = sPezDir .. sPezName .. '.nge'
+
+ -- Messaggi di inizio
+ EgtOutLog( 'Pez = ' .. sPezFile .. ' Model = ' .. sModFile)
+
+ -- Cancello tutti i file di output
+ EgtEraseFile( sErrFile)
+ EgtEraseFile( sCncFile)
+ EgtEraseFile( sNgeFile)
+
+ -- Pulisco il direttorio temporaneo
+ EgtEmptyDirectory( sTmpDir)
+
+ -- Apertura file errori
+ if not EGB.OpenErrFile( sErrFile) then
+ EgtOutLog( '(ERR=101) Errore nell\'apertura del file degli errori' .. sErrFile)
+ GGD.ERR = 101
+ return
+ end
+
+ -- Apertura file MOD
+ if not EGB.OpenFile( sModFile) then
+ EGB.WriteErrLine( 'ERR=102\nErrore nell\'apertura del file ' .. sModFile)
+ GGD.ERR = 102
+ return
+ end
+
+ -- Recupero header modello
+ if not GetHeader() then
+ EGB.WriteErrLine( 'ERR=103\nErrore in lettura NOME o MACH')
+ GGD.ERR = 103
+ return
+ end
+ EgtOutLog( 'Name = ' .. m_sModName .. ' Mach = ' .. m_sMachName .. ' Attr = ' .. m_sAttr)
+ if not EgtSetCurrMachine( m_sMachName) then
+ EGB.WriteErrLine( 'ERR=119\nErrore impostando la macchina corrente ' .. m_sMachName)
+ GGD.ERR = 119
+ return
+ end
+ local sMachIni = EgtGetCurrMachineDir() .. '\\' .. m_sMachName .. '.ini'
+ local bTwoHeads = ( EgtGetStringFromIni( 'Gunstock', 'TwoHeads', '0', sMachIni) == '1')
+ local bAddM6ToT3x = ( EgtGetStringFromIni( 'Gunstock', 'AddM6ToT3x', '1', sMachIni) == '1')
+
+ -- Recupero parametri (opzionali)
+ if not GetParams() then
+ EGB.WriteErrLine( 'ERR=104\nErrore in lettura PARAM')
+ GGD.ERR = 104
+ return
+ end
+ -- assegno i valori dal pezzo
+ for i = 1, #m_vParams do
+ local Param = m_vParams[i]
+ Param.dVal = m_vVals[i]
+ end
+ for i = 1, #m_vParams do
+ local Param = m_vParams[i]
+ EgtOutLog( 'Param = ' .. Param.sName ..
+ ' ' .. EgtNumToString( Param.dMin, 1) .. ' ' .. EgtNumToString( Param.dMax, 1) ..
+ ' ' .. EgtNumToString( Param.dDef, 1) .. ' ' .. Param.sVar ..
+ ' -> ' .. EgtNumToString( Param.dVal, 1))
+ end
+
+ -- Recupero variabili e ne valuto le espressioni
+ if not GetVars() then
+ EGB.WriteErrLine( 'ERR=105\nErrore in lettura VAR')
+ GGD.ERR = 105
+ return
+ end
+ EvaluateVars()
+ if GGD.ERR ~= 0 then
+ return
+ end
+
+ -- Recupero dimensioni grezzo e ne valuto le espressioni
+ if not GetRawDim() then
+ EGB.WriteErrLine( 'ERR=107\nErrore in lettura DIM_GREZZO')
+ GGD.ERR = 107
+ return
+ end
+ EvaluateRawDim()
+ if GGD.ERR ~= 0 then
+ return
+ end
+
+ -- Inizio lavorazioni piane
+ if not GetStartStdMachining() then
+ EGB.WriteErrLine( 'ERR=109\nErrore in lettura LAV_PIA_1')
+ GGD.ERR = 109
+ return
+ end
+
+ -- Recupero posizione grezzo e ne valuto le espressioni
+ if not GetRawRef() then
+ EGB.WriteErrLine( 'ERR=110\nErrore in lettura RIF_GRE')
+ GGD.ERR = 110
+ return
+ end
+ local bRawRefEval = true
+ for i = 1, #m_vRawRef do
+ local RawRef = m_vRawRef[i]
+ if RawRef.Type == 1 then
+ RawRef.dX = EvaluateExpr( RawRef.sXExpr)
+ RawRef.dY = EvaluateExpr( RawRef.sYExpr)
+ RawRef.dZ = EvaluateExpr( RawRef.sZExpr)
+ if not RawRef.dX or not RawRef.dY or not RawRef.dZ then bRawRefEval = false end
+ elseif RawRef.Type == 2 then
+ RawRef.dAng = EvaluateExpr( RawRef.sAngExpr)
+ if ( not RawRef.dAng or
+ ( RawRef.sAx ~= 'X' and RawRef.sAx ~= 'Y' and RawRef.sAx ~= 'Z') or
+ ( RawRef.sMode ~= 'F' and RawRef.sMode ~= 'M')) then bRawRefEval = false end
+ end
+ end
+ if not bRawRefEval then
+ EGB.WriteErrLine( 'ERR=111\nErrore nella valutazione del riferimento del grezzo')
+ GGD.ERR = 111
+ return
+ end
+ EgtOutLog( 'RawRef')
+ for i = 1, #m_vRawRef do
+ local RawRef = m_vRawRef[i]
+ if RawRef.Type == 1 then
+ EgtOutLog( 'Tras = X'..EgtNumToString( RawRef.dX, 3)..' Y'..EgtNumToString( RawRef.dY, 3)..
+ ' Z'..EgtNumToString( RawRef.dZ, 3))
+ elseif RawRef.Type == 2 then
+ EgtOutLog( 'Rotaz = '..RawRef.sAx..' '..RawRef.sMode..' '..EgtNumToString( RawRef.dAng, 3))
+ end
+ end
+
+ -- Recupero posizione finito e ne valuto le espressioni
+ if not GetGunRef() then
+ EGB.WriteErrLine( 'ERR=112\nErrore in lettura RIF_FUCILE')
+ GGD.ERR = 112
+ return
+ end
+ local bGunRefEval = true
+ for i = 1, #m_vGunRef do
+ local GunRef = m_vGunRef[i]
+ if GunRef.Type == 1 then
+ GunRef.dX = EvaluateExpr( GunRef.sXExpr)
+ GunRef.dY = EvaluateExpr( GunRef.sYExpr)
+ GunRef.dZ = EvaluateExpr( GunRef.sZExpr)
+ if not GunRef.dX or not GunRef.dY or not GunRef.dZ then bGunRefEval = false end
+ elseif GunRef.Type == 2 then
+ GunRef.dAng = EvaluateExpr( GunRef.sAngExpr)
+ if ( not GunRef.dAng or
+ ( GunRef.sAx ~= 'X' and GunRef.sAx ~= 'Y' and GunRef.sAx ~= 'Z') or
+ ( GunRef.sMode ~= 'F' and GunRef.sMode ~= 'M')) then bGunRefEval = false end
+ end
+ end
+ if not bGunRefEval then
+ EGB.WriteErrLine( 'ERR=113\nErrore nella valutazione del riferimento del pezzo')
+ GGD.ERR = 113
+ return
+ end
+ EgtOutLog( 'GunRef')
+ for i = 1, #m_vGunRef do
+ local GunRef = m_vGunRef[i]
+ if GunRef.Type == 1 then
+ EgtOutLog( 'Tras = X'..EgtNumToString( GunRef.dX, 3)..' Y'..EgtNumToString( GunRef.dY, 3)..
+ ' Z'..EgtNumToString( GunRef.dZ, 3))
+ elseif GunRef.Type == 2 then
+ EgtOutLog( 'Rotaz = '..GunRef.sAx..' '..GunRef.sMode..' '..EgtNumToString( GunRef.dAng, 3))
+ end
+ end
+
+ -- Recupero dati di lavorazione
+ while not GetEndStdMachining() do
+ if not GetMachining() then
+ EGB.WriteErrLine( 'ERR=114\nErrore in lettura Lavorazione (linea ' .. tostring( EGB.GetLineNumber()) ..')')
+ GGD.ERR = 114
+ return
+ end
+ local bStdMachEval = true
+ local vMach = m_vMachs[#m_vMachs]
+ if vMach.Ang then
+ vMach.Ang.dR1 = EvaluateExpr( vMach.Ang.sR1Expr)
+ vMach.Ang.dR2 = EvaluateExpr( vMach.Ang.sR2Expr)
+ if not vMach.Ang.dR1 or not vMach.Ang.dR2 then bStdMachEval = false end
+ end
+ if vMach.PrepRot then
+ vMach.PrepRot.dR1 = EvaluateExpr( vMach.PrepRot.sR1Expr)
+ vMach.PrepRot.dR2 = EvaluateExpr( vMach.PrepRot.sR2Expr)
+ vMach.PrepRot.dFeed = EvaluateExpr( vMach.PrepRot.sFeedExpr)
+ if not vMach.PrepRot.dR1 or not vMach.PrepRot.dR2 or not vMach.PrepRot.dFeed then bStdMachEval = false end
+ end
+ for i = 1, #vMach do
+ local Data = vMach[i]
+ if Data.Type == 1 then
+ Data.dX = EvaluateExpr( Data.sXExpr)
+ Data.dY = EvaluateExpr( Data.sYExpr)
+ Data.dZ = EvaluateExpr( Data.sZExpr)
+ if not Data.dX or not Data.dY or not Data.dZ then bStdMachEval = false end
+ elseif Data.Type == 2 then
+ Data.dAng = EvaluateExpr( Data.sAngExpr)
+ if ( not Data.dAng or
+ ( Data.sAx ~= 'X' and Data.sAx ~= 'Y' and Data.sAx ~= 'Z') or
+ ( Data.sMode ~= 'F' and Data.sMode ~= 'M')) then bStdMachEval = false end
+ end
+ end
+ if not bStdMachEval then
+ EGB.WriteErrLine( 'ERR=115\nErrore nella valutazione della lavorazione '.. vMach.sName)
+ GGD.ERR = 115
+ return
+ end
+ EgtOutLog( 'Mach ' .. vMach.sName)
+ EgtOutLog( 'Info = ' .. vMach.sInfo)
+ if vMach.Ang then
+ EgtOutLog( 'Ang = '..EgtNumToString( vMach.Ang.dR1, 3)..' '..EgtNumToString( vMach.Ang.dR2, 3))
+ end
+ if vMach.PrepRot then
+ EgtOutLog( 'PrepRot = '..EgtNumToString( vMach.PrepRot.dR1, 3)..' '..EgtNumToString( vMach.PrepRot.dR2, 3)..
+ ' '..EgtNumToString( vMach.PrepRot.dFeed, 3))
+ end
+ for i = 1, #vMach do
+ local Data = vMach[i]
+ if Data.Type == 1 then
+ EgtOutLog( 'Tras = X'..EgtNumToString( Data.dX, 3)..' Y'..EgtNumToString( Data.dY, 3)..
+ ' Z'..EgtNumToString( Data.dZ, 3))
+ elseif Data.Type == 2 then
+ EgtOutLog( 'Rotaz = '..Data.sAx..' '..Data.sMode..' '..EgtNumToString( Data.dAng, 3))
+ end
+ end
+ end
+
+ -- Chiusura file MOD
+ EGB.CloseFile()
+
+ -- Creazione grezzo
+ EgtNewFile()
+
+ local Pz = EgtGroup( GDB_ID.ROOT)
+ EgtSetName( Pz, 'GUNSTOCK')
+ local Ly = EgtGroup( Pz)
+ EgtSetName( Ly, 'SOLID')
+
+ local Sol
+ -- se definito sbozzato
+ if m_sSboName then
+ -- Inserimento file
+ local sSboFile = sSboDir .. m_sSboName
+ if EgtInsertFile( sSboFile) then
+ -- Spostamento contorno nel layer del solido
+ local nPz = EgtGetLastPart()
+ local nLay = EgtGetFirstLayer( nPz)
+ local nId = EgtGetFirstInGroup( nLay or GDB_ID.NULL)
+ EgtRelocate( nId, Ly)
+ EgtErase( nPz)
+ -- Lo spiano a Z=0
+ EgtScale( nId, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB)
+ -- Eventuale rototraslazione
+ if m_vSboMove then
+ EgtRotate( nId, ORIG(), Z_AX(), m_vSboMove.dR, GDB_RT.GLOB)
+ EgtMove( nId, Vector3d( m_vSboMove.dX, m_vSboMove.dY,0))
+ end
+ -- Creazione del solido
+ Sol = EgtSurfTmByRegionExtrusion( Ly, nId, Z_AX() * m_vRaw.dAlt * m_dCoeffAlt)
+ else
+ EgtOutLog( 'Error in InsertFile ' .. sSboFile)
+ end
+ end
+ -- creo parallelepipedo
+ if not Sol then
+ Sol = EgtSurfTmBox( Ly, ORIG(), Point3d( m_vRaw.dLen, -m_vRaw.dLar, 0), Point3d(10,0,0), m_vRaw.dAlt * m_dCoeffAlt, GDB_RT.GLOB)
+ end
+ EgtSetName( Sol, 'SOLID')
+ EgtSetColor( Sol, ORANGE())
+ EgtSetAlpha( Sol, 30)
+ -- calcolo delta tra Zero solido (sbozzato) e Zero teorico del grezzo
+ local b3Sol = EgtGetBBoxGlob( Sol, GDB_BB.EXACT)
+ local vtSolDelta = Vector3d( b3Sol:getMin():getX(), b3Sol:getMax():getY(), 0)
+
+ -- Calcolo riferimento del fucile
+ local frGun = Frame3d( GLOB_FRM())
+ for i = 1, #m_vGunRef do
+ local GunRef = m_vGunRef[i]
+ if GunRef.Type == 1 then
+ local vtMove = GunRef.dX * frGun:getVersX() + GunRef.dY * frGun:getVersY() + GunRef.dZ * frGun:getVersZ()
+ frGun:move( vtMove)
+ elseif GunRef.Type == 2 then
+ local vtAx
+ if GunRef.sAx == 'X' then
+ if GunRef.sMode == 'F' then vtAx = X_AX() else vtAx = frGun:getVersX() end
+ elseif GunRef.sAx == 'Y' then
+ if GunRef.sMode == 'F' then vtAx = Y_AX() else vtAx = frGun:getVersY() end
+ else -- 'Z'
+ if GunRef.sMode == 'F' then vtAx = Z_AX() else vtAx = frGun:getVersZ() end
+ end
+ frGun:rotate( frGun:getOrigin(), vtAx, GunRef.dAng)
+ end
+ end
+
+ -- Elaborazione delle lavorazioni
+ for i = 1, #m_vMachs do
+ -- lavorazione i-esima
+ local vMach = m_vMachs[i]
+ -- riferimento della lavorazione
+ local frMach = Frame3d( frGun)
+ for i = 1, #vMach do
+ local Data = vMach[i]
+ if Data.Type == 1 then
+ local vtMove = Data.dX * frMach:getVersX() + Data.dY * frMach:getVersY() + Data.dZ * frMach:getVersZ()
+ frMach:move( vtMove)
+ elseif Data.Type == 2 then
+ local vtAx
+ if Data.sAx == 'X' then
+ if Data.sMode == 'F' then vtAx = frGun:getVersX() else vtAx = frMach:getVersX() end
+ elseif Data.sAx == 'Y' then
+ if Data.sMode == 'F' then vtAx = frGun:getVersY() else vtAx = frMach:getVersY() end
+ else -- 'Z'
+ if Data.sMode == 'F' then vtAx = frGun:getVersZ() else vtAx = frMach:getVersZ() end
+ end
+ frMach:rotate( frMach:getOrigin(), vtAx, Data.dAng)
+ end
+ end
+ -- creo il layer
+ local Lm = EgtGroup( Pz, frMach)
+ EgtSetName( Lm, vMach.sName)
+ vMach.nLay = Lm
+ -- inserisco riferimento
+ local l = EgtFrame( Lm, Frame3d( ORIG()))
+ EgtSetName( l, 'Ref')
+ -- inserimento lavorazione (in ordine crecente di E)
+ local vSubst = { {'E1', '25.5'}, {'E2', '25.5'}, {'E101', '25.5'}, {'E102', '25.5'}}
+ if not EGB.ImportCnc( sSubDir, sTmpDir, 'Sub'..vMach.sName, vSubst, bAddM6ToT3x, vMach.nLay) then
+ EgtOutLog( 'Errore inserimento percorso di lavorazione ' .. vMach.sName)
+ end
+ end
+ EgtSetGridFrame()
+
+ -- Gestione macchina
+ if not EgtGetCurrMachineName() then
+ EGB.WriteErrLine( 'ERR=201\nErrore : non esiste una macchina corrente')
+ GGD.ERR = 201
+ return
+ end
+ -- Gestione tavola macchina
+ local nMchId = EgtAddMachGroup( 'Mach01')
+ EgtSetTable( 'Tab')
+ local tabOri = EgtGetTableRef( 1)
+ -- Posizionamento delle morse per calcio
+ local nFix
+ if m_vRaw.dLen < LEN_MIN_RIFLE then
+ nFix = EgtAddFixture( 'Vise2H85', Vector3d( 629, 350-1.49, 0), 0, m_vRaw.dAlt * m_dCoeffAlt)
+ else
+ nFix = EgtAddFixture( 'ViseRifle', Vector3d( 600, 350-1.49, 0), 0, m_vRaw.dAlt * m_dCoeffAlt)
+ end
+ -- Posizionamento del grezzo in macchina
+ local ColA = Color3d( 255, 165, 0, 30)
+ local nRaw = EgtAddRawPartWithPart( Pz, Sol, 0, ColA) or GDB_ID.NULL
+ EgtSetStatus( Sol, GDB_ST.ON)
+ local b3Raw = EgtGetBBoxGlob( Sol, GDB_BB.EXACT)
+ local ptRawCen = EgtGetRawPartCenter( nRaw)
+ --EgtOutLog( 'RawBox=' .. tostring( b3Raw))
+ --EgtOutLog( 'RawCen=' .. tostring( ptRawCen))
+ local ptPosTL = Point3d( 0, b3Raw:getDimY(), 0)
+ local bRawPartOk = EgtMoveToCornerRawPart( nRaw, ptPosTL, MCH_CR.TL)
+ local ptRef = Point3d( b3Raw:getMin():getX() - ptRawCen:getX(), b3Raw:getMax():getY() - ptRawCen:getY(), 0) - vtSolDelta
+ local ptNewRef = Point3d( ptRef)
+ for i = 1, #m_vRawRef do
+ local RawRef = m_vRawRef[i]
+ if RawRef.Type == 1 then
+ local vtMove = Point3d( RawRef.dX, RawRef.dY, RawRef.dZ) - ( tabOri + ptPosTL - vtSolDelta)
+ EgtOutLog( 'MoveRawPart=' .. tostring( vtMove))
+ if not EgtMoveRawPart( nRaw, Point3d( RawRef.dX, RawRef.dY, RawRef.dZ) - ( tabOri + ptPosTL - vtSolDelta)) then
+ bRawPartOk = false
+ end
+ elseif RawRef.Type == 2 then
+ local vtAx
+ if RawRef.sAx == 'X' then
+ vtAx = X_AX()
+ elseif RawRef.sAx == 'Y' then
+ vtAx = Y_AX()
+ else -- 'Z'
+ vtAx = Z_AX()
+ end
+ if not EgtRotateRawPart( nRaw, vtAx, RawRef.dAng) then
+ bRawPartOk = false
+ end
+ ptNewRef:rotate( ORIG(), vtAx, RawRef.dAng)
+ end
+ end
+ -- per compensare rotazione su centroide anzichè su angolo TL
+ --EgtOutLog( 'CompRot : ptRef='..tostring( ptRef)..' ptNewRef='..tostring( ptNewRef))
+ if not EgtMoveRawPart( nRaw, ptRef - ptNewRef) then
+ bRawPartOk = false
+ end
+ if not bRawPartOk then
+ EGB.WriteErrLine( 'ERR=202\nErrore : in creazione o posizionamento grezzo')
+ GGD.ERR = 202
+ return
+ end
+
+ -- Generazione programma principale
+ if not EGB.OpenOutFile( sCncFile) then
+ EGB.WriteErrLine( 'ERR=203\nErrore nell\'apertura del file cnc ' .. sCncFile)
+ GGD.ERR = 203
+ return
+ end
+ -- emissione intestazione
+ EGB.WriteOutLine( '(DIS,"CODICE=PRG1")')
+ EGB.WriteOutLine( '; ' .. EgtGetCurrMachineName():upper())
+ EGB.WriteOutLine( '; ' .. sPezName:upper() .. sPezExt:upper() .. '-' .. sModName:upper() .. sModExt:upper())
+ EGB.WriteOutLine( '; ' .. GGD.DESCR:upper())
+ EGB.WriteOutLine( '; ' .. m_sAttr:upper())
+ local sStart1Def = 'M70
"CICLI"'
+ if m_vRaw.dLen < LEN_MIN_RIFLE then
+ WriteOutLineFromIni( 'Gunstock', 'Start1', sStart1Def, sMachIni)
+ else
+ WriteOutLineFromIni( 'Gunstock', 'Start1_R', sStart1Def, sMachIni)
+ end
+ for i = 1, #m_vParams do
+ EGB.WriteOutLine( m_vParams[i].sVar .. '=' .. EgtNumToString( m_vParams[i].dVal, 3))
+ end
+ if ( bTwoHeads and #m_vMachs > 0) then
+ local sTcPos = EgtGetInfo( m_vMachs[1] .nLay, 'TCPOS')
+ if not sTcPos then
+ EGB.WriteErrLine( 'ERR=208\nErrore non trovata posizione utensile in CU')
+ GGD.ERR = 208
+ return
+ end
+ local nTcPos = tonumber( sTcPos:sub( 2))
+ EGB.WriteOutLine( EgtIf( nTcPos <= 18, 'M41M52', 'M42M51'))
+ EGB.WriteOutLine( sTcPos .. ' M6')
+ end
+ local sStart2Def = 'G79G0Z0
G79X-1500Y-1600C0B0'
+ if m_vRaw.dLen < LEN_MIN_RIFLE then
+ WriteOutLineFromIni( 'Gunstock', 'Start2', sStart2Def, sMachIni)
+ else
+ WriteOutLineFromIni( 'Gunstock', 'Start2_R', sStart2Def, sMachIni)
+ end
+ EGB.WriteOutLine( '(UAO,0)')
+ EGB.WriteOutLine( EgtIf( bTwoHeads, '(UOT,0,X0,U0,Y0,Z0,W0)', '(UOT,0,X0,Y0,Z0)'))
+ -- emissione dei posizionamenti e dei richiami delle lavorazioni
+ if not EgtSetCalcTool( 'Calc', 'H1', 1) then
+ EGB.WriteErrLine( 'ERR=204\nErrore nell\'impostazione dell\'utensile di calcolo')
+ GGD.ERR = 204
+ return
+ end
+ local dCalcLen = EgtTdbGetCurrToolParam( MCH_TP.LEN)
+ local nNum = 0
+ local dPrevR1, dPrevR2 = 9999, 9999
+ for i = 1, #m_vMachs do
+ -- lavorazione i-esima
+ local vMach = m_vMachs[i]
+ local frMach = EgtFR( vMach.nLay, GDB_ID.ROOT)
+ -- emissione info di lavorazione
+ nNum = nNum + 10
+ if vMach.sInfo then
+ EGB.WriteOutLine( 'N'..EgtNumToString(nNum,0)..' ; ' .. vMach.sInfo:upper())
+ else
+ EGB.WriteOutLine( 'N'..EgtNumToString(nNum,0)..' ; ***')
+ end
+ -- emissione info utensile
+ local sToolInfo = ''
+ local sTcPos = EgtGetInfo( vMach.nLay, 'TCPOS')
+ if sTcPos == 'T00' then
+ sToolInfo = sToolInfo .. 'T=PRECEDENTE'
+ elseif sTcPos then
+ sToolInfo = sToolInfo .. sTcPos:upper()
+ end
+ local sTcomp = EgtGetInfo( vMach.nLay, 'TCOMP')
+ if sTcomp then sToolInfo = sToolInfo .. ' H' .. sTcomp:upper() end
+ local sTname = EgtGetInfo( vMach.nLay, 'TNAME')
+ if sTname then sToolInfo = sToolInfo .. ' ' .. sTname:upper() end
+ EGB.WriteOutLine( '; ' .. sToolInfo)
+ -- calcolo angoli
+ local dNearR1, dNearR2 = 0, 0
+ if vMach.Ang then
+ dNearR1 = vMach.Ang.dR1
+ dNearR2 = vMach.Ang.dR2
+ end
+ local bRaOk, dR1, dR2 = EGB.GetAngMach( frMach:getVersZ(), dNearR1, dNearR2)
+ if not bRaOk then
+ EGB.WriteOutLine( '; ERRORE CALC ROTAX DI ' .. vMach.sName:upper())
+ EGB.WriteErrLine( 'ERR=205\nErrore nel calcolo assi rotanti di ' .. vMach.sName)
+ GGD.ERR = 205
+ return
+ else
+ vMach.Ang.dR1N = dR1
+ vMach.Ang.dR2N = dR2
+ if vMach.PrepRot and
+ ( abs( dR1 - dPrevR1) > GEO.EPS_ANG_SMALL or abs( dR2 - dPrevR2) > GEO.EPS_ANG_SMALL) then
+ local sOut = 'G90G0'..'B'..EgtNumToString( dR1 - vMach.PrepRot.dR1, 3)..
+ 'C'..EgtNumToString( dR2 - vMach.PrepRot.dR2, 3)
+ EGB.WriteOutLine( sOut)
+ sOut = 'G90G1'..'B'..EgtNumToString( dR1, 3)..'C'..EgtNumToString( dR2, 3)..
+ 'F'..EgtNumToString( vMach.PrepRot.dFeed, 0)
+ EGB.WriteOutLine( sOut)
+ else
+ local sOut = 'G90G0'..'B'..EgtNumToString( dR1, 3)..'C'..EgtNumToString( dR2, 3)
+ EGB.WriteOutLine( sOut)
+ end
+ dPrevR1 = dR1
+ dPrevR2 = dR2
+ if bTwoHeads then EGB.WriteOutLine( 'G400') end
+ EGB.WriteOutLine( '(UAO,0)')
+ -- calcolo posizione
+ local bLa1Ok, _, dX1, dY1, dZ1 = EgtGetCalcPositions( frMach:getOrigin(), dR1, dR2)
+ if not bLa1Ok then
+ EGB.WriteOutLine( '; ERRORE CALC UOT DI ' .. vMach.sName:upper())
+ EGB.WriteErrLine( 'ERR=206\nErrore nel calcolo UOT di ' .. vMach.sName)
+ GGD.Err = 206
+ return
+ end
+ local dX = dX1
+ local dY = dY1
+ local dZ = dZ1 - dCalcLen
+ if bTwoHeads then
+ EGB.WriteOutLine( '(UOT,0,X' .. EgtNumToString( dX, 3) .. ',U' .. EgtNumToString( dX, 3) ..
+ ',Y' .. EgtNumToString( dY, 3) ..
+ ',Z' .. EgtNumToString( dZ, 3) .. ',W' .. EgtNumToString( dZ, 3) .. ')')
+ else
+ EGB.WriteOutLine( '(UOT,0,X' .. EgtNumToString( dX, 3) ..
+ ',Y' .. EgtNumToString( dY, 3) ..
+ ',Z' .. EgtNumToString( dZ, 3) .. ')')
+ end
+ -- calcolo rotazione
+ local bLa2Ok, _, dX2, dY2, dZ2 = EgtGetCalcPositions( frMach:getOrigin() + 100*frMach:getVersX(), dR1, dR2)
+ if not bLa2Ok then
+ EGB.WriteOutLine( '; ERRORE CALC URT DI ' .. vMach.sName:upper())
+ EGB.WriteErrLine( 'ERR=207\nErrore nel calcolo URT di ' .. vMach.sName)
+ GGD.Err = 207
+ return
+ end
+ local dAng = atan2( dY2 - dY1, dX2 - dX1)
+ if abs( dZ2 - dZ1) > GEO.EPS_SMALL then
+ EgtOutLog( 'Differenza sensibile in Z per URT :'..EgtNumToString( dZ1, 6)..'/'..EgtNumToString( dZ2, 6))
+ end
+ EGB.WriteOutLine( '(URT,' .. EgtNumToString( dAng, 3) .. ')')
+ EGB.WriteOutLine( '(CLS,SUB' .. vMach.sName .. ')')
+ EGB.WriteOutLine( '(UAO,0)')
+ EGB.WriteOutLine( '(URT,0)')
+ end
+ end
+ -- emissione terminazione
+ local sEndDef = 'G79G0Z0
G79X-500Y-600C0B0
M63
M70
(GTO,CICLI,@SINGOLO=0)'
+ if m_vRaw.dLen < LEN_MIN_RIFLE then
+ WriteOutLineFromIni( 'Gunstock', 'End', sEndDef, sMachIni)
+ else
+ WriteOutLineFromIni( 'Gunstock', 'End_R', sEndDef, sMachIni)
+ end
+ EGB.WriteOutLine( 'M30')
+ -- chiusura file CNC
+ EGB.CloseOutFile()
+
+ -- Inserimento lavorazioni equivalenti
+ for i = 1, #m_vMachs do
+ -- lavorazione i-esima
+ local vMach = m_vMachs[i]
+ -- aggiungo lavorazione
+ local MachId = EgtAddMachining( vMach.sName, 'Calc')
+ if not MachId then
+ EGB.WriteErrLine( 'ERR=302\nErrore nel caricamento della lavorazione Calc')
+ GGD.ERR = 302
+ return
+ end
+ -- assegno i percorsi di lavorazione (pescandoli nel layer)
+ local vGeo = {}
+ local nId = EgtGetFirstInGroup( vMach.nLay)
+ while nId do
+ local nType = EgtGetType( nId)
+ if nType == GDB_TY.CRV_LINE or nType == GDB_TY.CRV_ARC or
+ nType == GDB_TY.CRV_BEZ or nType == GDB_TY.CRV_COMPO then
+ table.insert( vGeo, nId)
+ end
+ nId = EgtGetNext( nId)
+ end
+ EgtSetMachiningGeometry( vGeo)
+ -- assegno eventuali Hint sugli angoli
+ if vMach.Ang then
+ local sNotes = 'Hint:B=' .. EgtNumToString( vMach.Ang.dR1N, 3) .. ',C=' .. EgtNumToString( vMach.Ang.dR2N, 3) .. ';'
+ EgtOutLog( sNotes)
+ EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
+ end
+ -- applico
+ -- per ora lascio all'utente
+ -- la disabilito
+ EgtSetOperationMode( MachId, false)
+ end
+
+ -- Salvo il progetto
+ if not EgtSaveFile( sNgeFile) then
+ EGB.WriteErrLine( 'ERR=301\nErrore nel salvataggio del progetto ' .. sNgeFile)
+ GGD.ERR = 301
+ return
+ end
+
+ -- Messaggi di conclusione (con chiusura file errori)
+ EGB.WriteErrLine( 'ERR=0\nCompletato con successo')
+
+ GGD.ERR = 0
+
+end
+