-- EgtGunstockBase.lua by EgalTech s.r.l. 2022/06/20 -- 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 EgtOutLog( 'Error in CreateContext') return false end -- Esecuzione importazione if not EgtImportCnc( sCncFile, EIC_FL.CHAIN + EIC_FL.SKIP_ZEROMACH + EIC_FL.SKIP_RAPID) then EgtOutLog( 'Error in ImportCnc') return false end -- Salvataggio in formato Nge if not EgtSaveFile( sNgeFile, GDB_NT.BIN) then EgtOutLog( '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 EgtOutLog( '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 posizione utensile local sTPos = EgtGetInfo( nLay or GDB_ID.NULL, 'TPOS') if sTPos then EgtSetInfo( nLayId, 'TPOS', sTPos) end -- Copia eventuale info con speed local sSpeed = EgtGetInfo( nLay or GDB_ID.NULL, 'SPEED') if sSpeed then EgtSetInfo( nLayId, 'SPEED', sSpeed) 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, sExt, vSubst, bAddM6ToT3x, nLayId) local sSubFile = sDir .. sName .. ( sExt or '') local sCncFile = sTmpDir .. sName .. ( sExt or '.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