-- CncFagorToModCncOsai.lua by Egaltech s.r.l. 2022/07/15 -- Conversione CNC Fagor in Modello + CNC Osai -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( false) ----------------------------------------------------------------- -- Se espressione local function AdjustExpression( sExpr, vPar) for i = 1, #vPar do sExpr = sExpr:gsub( vPar[i][1], vPar[i][2]) end sExpr = sExpr:gsub( 'V.P.', '@') sExpr = sExpr:gsub( '%[', '(') sExpr = sExpr:gsub( '%]', ')') sExpr = sExpr:gsub( 'SQRT', 'sqrt') sExpr = sExpr:gsub( 'SQR', 'sqr') sExpr = sExpr:gsub( 'ASIN', 'asin') sExpr = sExpr:gsub( 'ACOS', 'acos') sExpr = sExpr:gsub( 'ATAN', 'atan') sExpr = sExpr:gsub( 'SIN', 'sin') sExpr = sExpr:gsub( 'COS', 'cos') sExpr = sExpr:gsub( 'TAN', 'tan') return sExpr end ----------------------------------------------------------------- -- Se linea MOD local function AdjustModLine( sLine, vPar) -- analisi linea originale local vsTok = EgtSplitString( sLine, ' ') local nG, sX, sY, sZ, dB, dU, nF, nM for i = 1, #vsTok do local sId = string.sub( vsTok[i], 1, 1) if sId == 'G' then nG = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'X' then sX = string.sub( vsTok[i], 2) sX = AdjustExpression( sX, vPar) elseif sId == 'Y' then sY = string.sub( vsTok[i], 2) sY = AdjustExpression( sY, vPar) elseif sId == 'Z' then sZ = string.sub( vsTok[i], 2) sZ = AdjustExpression( sZ, vPar) elseif sId == 'B' then dB = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'U' then dU = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'F' then nF = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'M' then nM = tonumber( string.sub( vsTok[i], 2)) elseif sId == ';' then break end end -- nuova linea local sNewLine = '' if nG == 181 then sNewLine = ' #TRAS X '..( sX or '0')..' Y '..( sY or '0')..' Z '..( sZ or '0') elseif nG == 182 then sNewLine = ' #ROTAZ ' local sAx, sRot if sX then sAx = 'X' sRot = sX elseif sY then sAx = 'Y' sRot = sY elseif sZ then sAx = 'Z' sRot = sZ end local sMF = EgtIf( nF == 1, ' F ', ' M ') sNewLine = sNewLine .. ( sAx or 'QQQ') .. sMF .. ( sRot or '0') elseif nG == 184 then sNewLine = ' #ANG ' .. EgtNumToString( dB or 0, 3) .. ' ' .. EgtNumToString( dU or 0, 3) elseif nG == 185 then sNewLine = ' #PREP_ROT ' .. EgtNumToString( dB or 0, 3) .. ' ' .. EgtNumToString( dU or 0, 3) .. ' ' .. EgtNumToString( nF or 0, 3) elseif nG == 186 then sNewLine = ' #TESTA_USCITA 1 1' end return sNewLine, nG end ----------------------------------------------------------------- -- Se linea con richiamo utensile local function AdjustToolLine( sLine) -- analisi linea originale local vsTok = EgtSplitStringPlus( sLine, 'TM;') local nT for i = 1, #vsTok do local sId = string.sub( vsTok[i], 1, 1) if sId == 'T' then nT = tonumber( string.sub( vsTok[i], 2)) end end -- nuova linea local sNewLine = '' if nT then sNewLine = sLine .. '\nh'..EgtNumToString( nT) else sNewLine = sLine end return sNewLine, nT end ----------------------------------------------------------------- -- Se linea con movimento, la sistemo e restituisco eventuali nuove quote X e Y local function AdjustMoveLine( sLine, dXp, dYp, nCp, nT) -- analisi linea originale local vsTok = EgtSplitStringPlus( sLine, 'GXYZIJRDFM;') local nG, nComp, dX, dY, dI, dJ, nD local nIndG, nIndComp, nIndI, nIndJ, nIndD nComp = nCp for i = 1, #vsTok do local sId = string.sub( vsTok[i], 1, 1) if sId == 'G' then local nVal = tonumber( string.sub( vsTok[i], 2)) if nVal then if nVal >= 0 and nVal <= 3 then nIndG = i nG = nVal elseif nVal >= 40 and nVal <= 42 then nIndComp = i nComp = nVal end end elseif sId == 'X' then dX = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'Y' then dY = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'I' then nIndI = i dI = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'J' then nIndJ = i dJ = tonumber( string.sub( vsTok[i], 2)) elseif sId == 'D' then nIndD = i nD = tonumber( string.sub( vsTok[i], 2)) elseif sId == ';' then break end end -- se compensazione su linea con movimento la lascio if dX or dY then nIndComp = nil nComp = nil end -- nuova linea local sNewLine = '' if nG and nG >= 0 and nG <= 3 then if nIndD then local nCorr = EgtIf( nD ==1, nT, 100 + nT) sNewLine = 'h' .. EgtNumToString( nCorr) .. '\n' end for i = 1, #vsTok do if i == nIndG then sNewLine = sNewLine .. vsTok[i] if nCp then sNewLine = sNewLine .. 'G' .. EgtNumToString( nCp, 0) .. ' ' if nComp == nCp then nComp = nil end end elseif i == nIndI and dI then sNewLine = sNewLine .. 'I' .. EgtNumToString( dI + dXp, 3) .. ' ' if not nIndJ then sNewLine = sNewLine .. 'J' .. EgtNumToString( dYp, 3) .. ' ' end elseif i == nIndJ and dJ then if not nIndI then sNewLine = sNewLine .. 'I' .. EgtNumToString( dXp, 3) .. ' ' end sNewLine = sNewLine .. 'J' .. EgtNumToString( dJ + dYp, 3) .. ' ' elseif i == nIndD then ; elseif i == nIndComp then ; else sNewLine = sNewLine .. vsTok[i] end end elseif nIndD then local nCorr = EgtIf( nD ==1, nT, 100 + nT) sNewLine = 'h' .. EgtNumToString( nCorr) .. '\n' if nCp and ( dX or dY) then sNewLine = sNewLine .. 'G' .. EgtNumToString( nCp, 0) .. ' ' if nComp == nCp then nComp = nil end end for i = 1, #vsTok do if i == nIndD then ; elseif i == nIndComp then ; else sNewLine = sNewLine .. vsTok[i] end end elseif nIndComp then if nCp and ( dX or dY) then sNewLine = sNewLine .. 'G' .. EgtNumToString( nCp, 0) .. ' ' if nComp == nCp then nComp = nil end end for i = 1, #vsTok do if i == nIndComp then ; else sNewLine = sNewLine .. vsTok[i] end end elseif dX or dY then if nCp then sNewLine = sNewLine .. 'G' .. EgtNumToString( nCp, 0) .. ' ' if nComp == nCp then nComp = nil end end sNewLine = sNewLine..sLine else sNewLine = sLine end return sNewLine, dX, dY, nComp end ----------------------------------------------------------------- -- Selezione del programma da convertire local sSouPath = EgtFileDialog( true, 'Cnc Fagor', 'File Cnc Fagor (*.mof)|*.mof||') if not sSouPath then EgtOutBox( 'Operation canceled', 'CncFagorToModCncOsai', 'INFO') return end -- Apro il file selezionato local SouFh = io.open( sSouPath, 'r') if not SouFh then EgtOutBox( 'Error opening ' .. sSouPath, 'CncFagorToModCncOsai', 'ERROR') return end -- Apro i file destinazione local sDir, sName, sExt = EgtSplitPath( sSouPath) local sCncPath = sDir .. sName .. '.cnc' local CncFh = io.open( sCncPath, 'w+') if not CncFh then SouFh:close() EgtOutBox( 'Error opening ' .. sCncPath, 'CncFagorToModCncOsai', 'ERROR') return end local sModPath = sDir .. sName .. '.mod' local ModFh = io.open( sModPath, 'w+') if not ModFh then SouFh:close() CncFh:close() EgtOutBox( 'Error opening ' .. sModPath, 'CncFagorToModCncOsai', 'ERROR') return end -- Ciclo sulle linee del file sorgente local nType = 0 -- 0 = inutile, 1 per MOD, 2 per CNC local nModFlag = 0 -- 0 = non definito, 1 = riferimenti, 2 = lavorazioni local nCntTras = 0 -- conteggio traslazioni in riferimenti local vPar = {} local nT local nComp local bHsc local dXp, dYp local sLine = SouFh:read( '*l') while sLine do sLine = EgtTrim( sLine) local nSubType = 0 -- 0 = intermedio, 1 = inizio, 2 = fine if string.find( sLine, ';#NOME', 1, true) then nType = 1 nSubType = 1 nModFlag = 1 elseif string.find( sLine, '%L SET_PARAMETRI', 1, true) then nType = 1 nSubType = 1 nModFlag = 2 elseif string.find( sLine, '%L SET_RIFERIMENTO_LAV1', 1, true) then nType = 1 nSubType = 1 nModFlag = 3 elseif string.find( sLine, '%PRG', 1, true) then nType = 1 nSubType = 1 nModFlag = 4 elseif string.find( sLine, '%L SUB', 1, true) then nType = 2 nSubType = 1 elseif string.find( sLine, '#RET', 1, true) or string.find( sLine, 'M30', 1, true) then nSubType = 2 end -- per MOD if nType == 1 then -- inizio if nSubType == 1 then if nModFlag == 1 then ModFh:write( '------------ Sezione 1 : dichiarazione nome del modello\n\n') ModFh:write( '#NOME '.. sName..'\n\n') ModFh:write( '#MACH MAT5517\n\n') ModFh:write( '#ATTR attrezzaggio\n\n') ModFh:write( '---------------- Sezione 2 : dichiarazione lavorazioni piane fase 1\n\n') elseif nModFlag == 2 then ModFh:write( '#END_PAR\n\n') elseif nModFlag == 3 then ModFh:write( '#END_VAR\n\n') ModFh:write( ' #LUNG_GREZZO 275\n') ModFh:write( ' #LARG_GREZZO 60\n') ModFh:write( ' #ALT_GREZZO 51\n') ModFh:write( ' #SBO Beretta ASTA.nge\n') ModFh:write( ' #MUOVI_SBO X0 Y0 R0\n') ModFh:write( '#END_DIM_GREZZO\n\n') ModFh:write( '#LAV_PIA_1\n\n') ModFh:write( ' #RIF_GRE\n') end -- fine elseif nSubType == 2 then if nModFlag == 2 then sLine = '' elseif nModFlag == 3 then sLine = ' #END_RIF\n' elseif nModFlag == 4 then sLine = '#END_PIA_1\n' end if #sLine > 0 then ModFh:write( sLine .. '\n') end nType = 0 -- intermedio else -- se linea dichiarazione parametro if sLine:sub( 1, 7) == ';#PARAM' then local vsTok = EgtSplitString( sLine, ' ') if #vsTok >= 6 then table.insert( vPar, { vsTok[6], '@'..vsTok[2]}) else EgtOutLog( 'Linea '..sLine..'con campi in numero insufficiente') end sLine = sLine:gsub( 'P1', 'E') sLine = ' '..sLine:sub( 2) -- se linea dichiarazione variabile elseif sLine:sub( 1, 4) == 'V.P.' then sLine = sLine:sub( 5) sLine = sLine:gsub( '=', '') sLine = AdjustExpression( sLine, vPar) sLine = ' #VAR '..sLine -- se linea di commento speciale, la elimino elseif sLine:sub( 1, 2) == ';#' then sLine = '' -- se inizio richiamo lavorazione elseif sLine:sub( 1, 17) == '; Esecuzione: SUB' then sLine = ' #LAV ' .. sLine:sub( 18) -- se linea di commento, la indento elseif sLine:sub( 1, 1) == ';' then sLine = ' ' .. sLine -- se linea di richiamo sottoprogramma elseif sLine:sub( 1, 9) == '#CALL SUB' then sLine = ' #END_SING_LAV\n' -- altrimenti la interpreto else local nG sLine, nG = AdjustModLine( sLine, vPar) if nModFlag == 3 and nG == 181 then nCntTras = nCntTras + 1 if nCntTras == 1 then sLine = sLine .. '\n #END_RIF\n\n #RIF_FUCILE' end end end -- emetto la linea, se non vuota if #sLine > 0 then ModFh:write( sLine .. '\n') end end -- per CNC elseif nType == 2 then -- inizio if nSubType == 1 then local sSub = sLine:gsub( '%%L SUB', '') CncFh:write( '(DIS,"CODICE=SUB'..sSub..'")\n') CncFh:write( '%\n') -- fine elseif nSubType == 2 then -- se attivo comando alta velocità, devo disabilitarlo if bHsc then bHsc = false CncFh:write( '#G355 H3\n') end CncFh:write( '%\n') nType = 0 -- intermedio else -- se linea di commento if sLine:sub( 1, 1) == ';' then ; -- se linea con comando alta velocità elseif sLine:sub( 1, 4) == '#HSC' then if sLine:find( 'ON', 1, true) then bHsc = true sLine = '#G355 H5' else bHsc = false sLine = '#G355 H3' end -- altrimenti else -- sostituzioni preliminari sLine = sLine:gsub( 'G187', 'G79') sLine = sLine:gsub( 'T21', '') sLine = sLine:gsub( 'T41', '') sLine = sLine:gsub( 'T42', '') sLine = sLine:gsub( 'T43', '') sLine = sLine:gsub( 'T31', 'T11') sLine = sLine:gsub( 'T32', 'T18') sLine = sLine:gsub( 'T33', 'T17') -- se linea con arresto utensile if sLine:find( 'M05', 1, true) or sLine:find( 'M5', 1, true) then sLine = 'M05' -- se altrimenti linea con richiamo utensile elseif sLine:find( 'M06', 1, true) or sLine:find( 'M6', 1, true) then local nNewT sLine, nNewT = AdjustToolLine( sLine) if nNewT then nT = nNewT end -- altrimenti linea di possibile movimento else -- sistemo dati di movimento (I e J di archi da relativo ad assoluto) local dNewX, dNewY sLine, dNewX, dNewY, nComp = AdjustMoveLine( sLine, dXp, dYp, nComp, nT) if dNewX then dXp = dNewX end if dNewY then dYp = dNewY end end end -- emetto la linea, se non vuota if #sLine > 0 then CncFh:write( sLine .. '\n') end end end -- passo alla linea successiva sLine = SouFh:read( '*l') end -- Chiudo i file SouFh:close() CncFh:close() ModFh:close() EgtOutBox( 'Operation completed with success', 'CncFagorToModCncOsai', 'INFO')