diff --git a/BatchProcess.lua b/BatchProcess.lua new file mode 100644 index 0000000..56d6b9a --- /dev/null +++ b/BatchProcess.lua @@ -0,0 +1,493 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2020/06/12 +-- Gestione calcolo batch disposizione e lavorazioni per Pareti + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--WALL = {} +--WALL.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFabio\\BTL_TS37\\Bar_25_2.btl' +--WALL.MACHINE = '90480019_MW' +--WALL.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if WALL.FLAG == 0 then + sFlag = 'GENERATE' +elseif WALL.FLAG == 1 then + sFlag = 'MODIFY' +elseif WALL.FLAG == 2 then + sFlag = 'SIMULATE' +elseif WALL.FLAG == 3 then + sFlag = 'CHECK' +elseif WALL.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif WALL.FLAG == 11 then + sFlag = 'TOOLS' +elseif WALL.FLAG == 12 then + sFlag = 'JOBS' +else + sFlag = 'FLAG='..tostring( WALL.FLAG) +end +local sLog = 'BatchProcess : ' .. WALL.FILE .. ', ' .. WALL.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( WALL.FILE, '.txt') +EgtEraseFile( sLogFile) + +-- Funzioni per scrittura su file di log specifico +local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId) + local hFile = io.open( sLogFile, 'a') + hFile:write( 'ERR=' .. tostring( nErr) .. '\n') + hFile:write( sMsg .. '\n') + hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n') + hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n') + hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n') + hFile:close() +end +local function WriteTimeToLogFile( dTime) + local hFile = io.open( sLogFile, 'a') + hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n') + hFile:close() +end + +-- Funzione per gestire visualizzazione dopo errore +local function PostErrView( nErr, sMsg) + if nErr ~= 0 and ( WALL.FLAG == 1 or WALL.FLAG == 2) then + EgtSetView( SCE_VD.ISO_SW, false) + EgtZoom( SCE_ZM.ALL) + EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS') + end +end + +-- Funzione per gestire visualizzazione dopo warning +local function PostWarnView( nWarn, sMsg) + if nWarn ~= 0 and ( WALL.FLAG == 1 or WALL.FLAG == 2) then + EgtSetView( SCE_VD.ISO_SW, false) + EgtZoom( SCE_ZM.ALL) + EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS') + end +end + +-- Funzione per aggiornare dati ausiliari +local function UpdateAuxData( sAuxFile) + local bModif = false + -- Se definito LOAD90, aggiorno + local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile) + if sLoad90 ~= '' then + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL + EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90) + bModif = true + end + return bModif +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Impostazione della macchina corrente +EgtResetCurrMachGroup() +local sMachine = 'Essetre-' .. WALL.MACHINE +if not EgtSetCurrMachine( sMachine) then + WALL.ERR = 11 + WALL.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + WALL.ERR = 12 + WALL.MSG = 'Error not configured for walls machine : ' .. sMachine + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if WALL.FLAG > 10 then + WALL.ERR = 0 + return +end + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +--local BL = require( 'BeamLib') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( WALL.FILE) +local bBtl = ( string.upper( sExt or '') ~= '.NGE') +local sNgeFile = sDir..sTitle..'.nge' +local sBtmFile = sDir..sTitle..'.btm' + +-- In generale va completamente riprocessato +local bToProcess = true +local bToRecalc = false +-- se BTL, barra ed esiste già il corrispondente progetto Nge +if bBtl and string.find( sTitle, 'Bar_', 1, true) and EgtExistsFile( sNgeFile) then + local sOriFile = sDir..sTitle..'.ori'..sExt + local sDiffFile = sDir..sTitle..'.diff.txt' + EgtEraseFile( sDiffFile) + local _, nDiff = EgtTextFileCompare( WALL.FILE, sOriFile, ';', sDiffFile) + -- se BTL corrente coincide con originale, salto il riprocessamento + if nDiff == 0 then + bToProcess = false + -- se cambiata configurazione macchina da ultima elaborazione, devo riprocessare + if EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Beam\\TS3Data.lua') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Tools\\Tools.data') == -1 then + bToRecalc = true + end + end +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 + +-- Se da elaborare +if bToProcess then + EgtOutLog( ' +++ Processing Parts >>>') + -- Se Btl, lo importo + if bBtl then + -- cancello eventuale vecchio progetto omonimo + EgtEraseFile( sNgeFile) + -- eseguo import + EgtNewFile() + if not EgtImportBtl( WALL.FILE, EIB_FL.TS3_POS + EIB_FL.USEUATTR) then + WALL.ERR = 13 + WALL.MSG = 'Error importing BTL file : ' .. WALL.FILE + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + -- faccio copia del file btl originale + EgtCopyFile( WALL.FILE, sDir..sTitle..'.ori'..sExt) + -- altrimenti Nge, lo apro + else + if not EgtOpenFile( WALL.FILE) then + WALL.ERR = 13 + WALL.MSG = 'Error opening NGE file : ' .. WALL.FILE + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( WALL.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Dimensioni del pannello + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELLEN', 'd') or 8000) + local dRawW = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELWIDTH', 'd') or 4000) + + -- Recupero l'elenco ordinato delle pareti + local vWall = {} + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vWall, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vWall == 0 then + WALL.ERR = 14 + WALL.MSG = 'Error no beams in the file : ' .. WALL.FILE + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + local sOut = '' + for i = 1, #vWall do + sOut = sOut .. vWall[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + + -- Ne recupero le dimensioni + for i = 1, #vWall do + local Ls = EgtGetFirstNameInGroup( vWall[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + WALL.ERR = 15 + WALL.MSG = 'Box undefined for beam ' .. vWall[i].Name + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + vWall[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + for i = 1, #vWall do + local PosX = EgtGetInfo( vWall[i].Id, 'POSX', 'd') + vWall[i].PosX = PosX + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') + vWall[i].PosZ = PosZ + end + + -- Eseguo eventuali rotazioni e inversioni testa-coda + for i = 1, #vWall do + local b3Solid = vWall[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vWall[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end + end + + -- Ne verifico le dimensioni + local dRawH = vWall[1].Box:getDimZ() + local vWallErr = {} + for i = 2, #vWall do + local dDimH = vWall[i].Box:getDimZ() + if abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL then + table.insert( vWallErr, i) + end + end + if #vWallErr > 0 then + local sOut = 'Rimosse pareti con spessore diverso dalla prima :\n' + for i = #vWallErr, 1, -1 do + sOut = sOut .. vWall[vWallErr[i]].Name .. '\n' + table.remove( vWall, vWallErr[i]) + end + WALL.ERR = 16 + WALL.MSG = sOut + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + -- Verifico dimensioni massime grezzo + if dRawL > WD.MAX_LENGTH + 10 * GEO.EPS_SMALL or dRawW > WD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > WD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Grezzo (' .. EgtNumToString( dRawL, 2) .. ' x ' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre il limite della macchina ('..EgtNumToString( WD.MAX_LENGTH, 2)..' x '..EgtNumToString( WD.MAX_WIDTH, 2)..' x '..EgtNumToString( WD.MAX_HEIGHT, 2)..') ' + WALL.ERR = 17 + WALL.MSG = sOut + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + -- Verifico dimensioni minime del grezzo + if dRawL < WD.MIN_LENGTH - 10 * GEO.EPS_SMALL or dRawW < WD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < WD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Grezzo (' .. EgtNumToString( dRawL, 2) .. ' x ' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto il limite della macchina ('..EgtNumToString( WD.MIN_LENGTH, 2)..' x '..EgtNumToString( WD.MIN_WIDTH, 2)..' x '..EgtNumToString( WD.MIN_HEIGHT, 2)..')' + WALL.ERR = 17 + WALL.MSG = sOut + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + -- Sistemo le pareti nel grezzo + local bPbOk, sPbErr = WE.ProcessWalls( dRawL, dRawW, dRawH, vWall) + if not bPbOk then + WALL.ERR = 18 + WALL.MSG = sPbErr + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( WALL.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Lavoro le features + local bPfOk, Stats = WE.ProcessFeatures() + local sOutput = '' + for i = 1, #Stats do + local sMsg = Stats[i].Msg + sMsg = string.gsub( sMsg, '\n', ' ', 10) + sMsg = string.gsub( sMsg, '\r', ' ', 10) + if Stats[i].Err == 0 then + WALL.ERR = 0 + WALL.MSG = '---' + WALL.ROT = Stats[i].Rot or 0 + WALL.CUTID = Stats[i].CutId + WALL.TASKID = Stats[i].TaskId + WriteErrToLogFile( WALL.ERR, WALL.MSG, WALL.ROT, WALL.CUTID, WALL.TASKID) + elseif Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, sMsg) + WALL.ERR = 19 + WALL.MSG = sMsg + WALL.ROT = Stats[i].Rot or 0 + WALL.CUTID = Stats[i].CutId + WALL.TASKID = Stats[i].TaskId + WriteErrToLogFile( WALL.ERR, WALL.MSG, WALL.ROT, WALL.CUTID, WALL.TASKID) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, sMsg) + WALL.ERR = -19 + WALL.MSG = sMsg + WALL.ROT = Stats[i].Rot or 0 + WALL.CUTID = Stats[i].CutId + WALL.TASKID = Stats[i].TaskId + WriteErrToLogFile( WALL.ERR, WALL.MSG, WALL.ROT, WALL.CUTID, WALL.TASKID) + end + end + + -- Salvo il progetto + EgtSaveFile( sNgeFile) + + -- Visualizzazione avvisi o errori + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + PostErrView( 19, sOutput) + elseif nWarnCnt > 0 then + PostWarnView( 19, sOutput) + end + +-- Altrimenti carico il progetto salvato e dichiaro nessun errore +else + EgtOutLog( ' +++ Loading Project already processed >>>') + -- Carico il progetto già fatto + EgtOpenFile( sNgeFile) + -- Dichiaro nessun errore + local nPartId = EgtGetFirstPart() + while nPartId do + local nCutId = EgtGetInfo( nPartId, 'CUTID') + if nCutId then + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local bIsFea = EgtExistsInfo( nProcId, 'GRP') and EgtExistsInfo( nProcId, 'PRC') + local nTaskId = EgtGetInfo( nProcId, 'TASKID') + if bIsFea and nTaskId then + WALL.ERR = 0 + WALL.MSG = '---' + WALL.ROT = 0 + WALL.CUTID = nCutId + WALL.TASKID = nTaskId + WriteErrToLogFile( WALL.ERR, WALL.MSG, WALL.ROT, WALL.CUTID, WALL.TASKID) + end + nProcId = EgtGetNext( nProcId) + end + end + nPartId = EgtGetNextPart( nPartId) + end + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + -- Passo in modalità lavora + EgtSetCurrMachGroup( EgtGetLastMachGroup()) + -- Se necessario eseguo aggiornamento con ricalcolo delle lavorazioni + if bToRecalc then + EgtOutLog( ' +++ Recalculating all dispositions and machinings >>>') + EgtApplyAllMachinings() + -- copia del file btl originale (per dichiarare progetto ricalcolato) + EgtCopyFile( WALL.FILE, sDir..sTitle..'.ori'..sExt) + end + -- Salvo il progetto + EgtSaveFile( sNgeFile) +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( WALL.FLAG == 0 and ( bToProcess or bToRecalc)) or WALL.FLAG == 3 or WALL.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + WALL.ERR = 19 + WALL.MSG = 'Error in clamps disposition' + elseif nErr == MCH_SHE.COLLISION then + WALL.ERR = 22 + WALL.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + WALL.ERR = 23 + WALL.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + WALL.ERR = 24 + WALL.MSG = 'Clamp move error ' .. sErr + else + WALL.ERR = 25 + WALL.MSG = 'General failure (contact supplier)' + end + WALL.ROT = 0 + WALL.CUTID = 0 + WALL.TASKID = 0 + local vItem = EgtSplitString( sErr, ';') or {} + for i = 1, #vItem do + vItem[i] = EgtTrim( vItem[i] or '') + if string.find( vItem[i], 'CUTID', 1, true) then + WALL.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + WALL.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( WALL.ERR, WALL.MSG, WALL.ROT, WALL.CUTID, WALL.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if WALL.FLAG == 0 or WALL.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + WALL.ERR = 20 + local _, sName, _ = EgtSplitPath( WALL.FILE) + WALL.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + + WALL.ERR = 21 + local _, sName, _ = EgtSplitPath( WALL.FILE) + WALL.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return +end +local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Imposto la vista ISO 3d, se richiesto +if WALL.FLAG == 1 or WALL.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + WALL.ERR = 0 + WALL.MSG = '---' + WriteErrToLogFile( WALL.ERR, WALL.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..da62d7c --- /dev/null +++ b/LuaLibs/MachiningLib.lua @@ -0,0 +1,108 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2020/06/24 +-- Libreria ricerca lavorazioni per Pareti + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' MachiningLib started', 1) + +-- Dati +local WD = require( 'WallData') +local Cuttings = require( 'CutData') +local Millings = require( 'MillingData') +local Pocketings = require( 'PocketingData') +local Sawings = require( 'SawingData') +local Drillings = require( 'DrillData') + +--------------------------------------------------------------------- +local function SetCurrMachiningAndTool( sMachName) + if not EgtMdbSetCurrMachining( sMachName) then return false end + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + local sTool = EgtTdbGetToolFromUUID( sTuuid) + if not sTool then return false end + if not EgtTdbSetCurrTool( sTool) then return false end + return EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) +end + +--------------------------------------------------------------------- +function MachiningLib.FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.On and Cutting.Type == sType and SetCurrMachiningAndTool( Cutting.Name) then + return Cutting.Name + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindMilling( sType, dDepth, sTuuidMstr) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == sType and SetCurrMachiningAndTool( Milling.Name) then + local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + if ( not sTuuidMstr or sTuuidMstr == sTuuid) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) then + return Milling.Name, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindPocketing( sType, dMaxDiam, dDepth) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.On and Pocketing.Type == sType and SetCurrMachiningAndTool( Pocketing.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + if ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) then + return Pocketing.Name, dTDiam, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindSawing( sType) + for i = 1, #Sawings do + local Sawing = Sawings[i] + if Sawing.On and Sawing.Type == sType and SetCurrMachiningAndTool( Sawing.Name) then + return Sawing.Name + end + end + +end + +--------------------------------------------------------------------- +function MachiningLib.FindDrilling( dDiam) + -- ricerca sulle forature, dal diametro maggiore al minore + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == 'Drill' and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + if dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - WD.DRILL_TOL - 10 * GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxMat + end + end + end + -- ricerca sulle svuotature, dal diametro maggiore al minore + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == 'Pocket' and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + if dTDiam < dDiam - 10 * GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxDepth + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +return MachiningLib diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..45682bd --- /dev/null +++ b/LuaLibs/ProcessDrill.lua @@ -0,0 +1,189 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2020/06/24 +-- Gestione calcolo forature per Pareti + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local WD = require( 'WallData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function ProcessDrill.GetData( Proc) + -- verifico se foro da adattare + if EgtExistsInfo( Proc.Id, 'DiamUser') then + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if AuxId and EgtGetType( AuxId) == GDB_TY.CRV_ARC and WD.USER_HOLE_DIAM and WD.USER_HOLE_DIAM > 1 then + EgtModifyArcRadius( AuxId, WD.USER_HOLE_DIAM / 2) + EgtSetInfo( Proc.Id, 'P12', WD.USER_HOLE_DIAM) + end + end + -- recupero diametro + local dDiam = EgtGetInfo( Proc.Id, 'P12', 'd') or 0 + -- recupero faccia di entrata e uscita + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return dDiam, nFcs, nFce +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.Classify( Proc, b3Raw) + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + -- recupero i dati del foro + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptCen = EgtCP( AuxId, GDB_RT.GLOB) + -- verifico se troppo inclinato e quindi non lavorabile + if not ( Proc.Fcs == 5 or Proc.Fcs == 6 or Proc.Fce == 5 or Proc.Fce == 6) and abs( vtExtr:getX()) > WD.DRILL_VX_MAX then + return false + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2) + -- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco + if (( vtExtr:getZ() < WD.DRILL_VZ_MIN or bFaceDown) and not bOpen) then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing drill geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati del foro + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < 0) + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + if Proc.Fcs == 0 then bToInvert = true end + if bToInvert then vtExtr = - vtExtr end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dDiamTh = 35 + if EgtMdbSetCurrMachining( sDrilling) then + local bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING) + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + if bIsDrilling then + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + else + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + dDiamTh = EgtTdbGetCurrToolThDiam() + end + end + -- se foro intermedio e inclinato, limito il massimo affondamento + if not ( ( Proc.Fcs == 5 or Proc.Fcs == 6) or ( bToInvert and ( Proc.Fce == 5 or Proc.Fce == 6))) then + local CosB = abs( vtExtr:getX()) + if CosB < WD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA + else + dMaxDepth = 0 + end + end + -- inserisco la lavorazione + local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sDrilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eventuale inversione + if nType == 'Drill' then + EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtExtr:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiusto l'affondamento + local sMyWarn + local dDepth = dLen + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth + EgtOutLog( sMyWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- se foratura + if nType == 'Drill' then + -- aggiungo alle note massima elevazione (coincide con affondamento) + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + -- se foro passante, aggiungo questa qualifica alle note + if bOpen then + sUserNotes = sUserNotes .. 'Open=1;' + end + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + local _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + return false, sWarn + else + return true, ( sMyWarn or sWarn) + end + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +return ProcessDrill diff --git a/LuaLibs/ProcessFreeContour.lua b/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..139576f --- /dev/null +++ b/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,216 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2020/06/24 +-- Gestione calcolo profilo libero per Pareti + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +--local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local WD = require( 'WallData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFreeContour.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and ( Proc.Prc == 250 or Proc.Prc == 251 or Proc.Prc == 252)) +end + + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFreeContour.Classify( Proc, b3Raw) + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se tasca + if bPocket then + local bDown = ( vtN:getZ() < - 0.5) + return false + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return false + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() - 2 then + return false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + return true + end +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nRawId, b3Raw) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( Proc.PartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + local bToolInv = ( vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'FreeContour') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + --BL.PutStartOnLonger( AuxId) + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + WD.CUT_EXTRA + end + if dDepth > dMaxDepth then + dDepth = dMaxDepth + end + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- se estrusione da sotto, inverto direzione fresa + if bToolInv then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if Proc.Grp == 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + elseif ( Proc.Grp == 3 and not bToolInv) or ( Proc.Grp == 4 and bToolInv) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + elseif ( Proc.Grp == 3 and bToolInv) or ( Proc.Grp == 4 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByPocket( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + --local bToolInv = ( vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local sPocketing = ML.FindPocketing( 'Pocket', nil, dDepth) + if not sPocketing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth + local sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessFreeContour.Make( Proc, nRawId, b3Raw) + -- recupero la tipologia + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nRawId, b3Raw) + -- altrimenti contornatura + else + return MakeByMill( Proc, nRawId, b3Raw) + end +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/LuaLibs/WallExec.lua b/LuaLibs/WallExec.lua new file mode 100644 index 0000000..8c72d03 --- /dev/null +++ b/LuaLibs/WallExec.lua @@ -0,0 +1,204 @@ +-- WallExec.lua by Egaltech s.r.l. 2020/06/24 +-- Libreria esecuzione lavorazioni per Pareti + +-- Tabella per definizione modulo +local WallExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali e libero tutti gli altri +_G.package.loaded.WallData = nil +local WD = require( 'WallData') + +-- Carico le librerie +_G.package.loaded.MachiningLib = nil +local BM = require( 'MachiningLib') +_G.package.loaded.ProcessDrill = nil +local Drill = require( 'ProcessDrill') +_G.package.loaded.ProcessFreeContour = nil +local FreeContour = require( 'ProcessFreeContour') + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle pareti nel pannello *** +------------------------------------------------------------------------------------------------------------- +function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall) + + -- Creazione nuovo gruppo di lavoro + local sMgName = EgtGetMachGroupNewName( 'Mach') + local NewMgId = EgtAddMachGroup( sMgName) + if not NewMgId then + local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName + return false, sOut + end + -- Impostazione della tavola + EgtSetTable( 'Tab') + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo BR della tavola rispetto a sua origine in BL + WD.OriBR = Point3d( b3Tab:getDimX(), 0, 0) + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + -- Creazione del grezzo e suo posizionamento in macchina + local nRaw = EgtAddRawPart( Point3d(0,0,0), dRawL, dRawW, dRawH, WD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, WD.OriBR, MCH_CR.BR) + -- Inserimento dei pezzi nel grezzo + for i = 1, #vWall do + -- assegno identificativo pezzo + local Pz = vWall[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vWall[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = Point3d( dRawL - vWall[i].PosX - PartLen, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle pareti *** +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Outline') + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, #LayerId do + local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) + while ProcId do + 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 nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 + local nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 + local nTaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 + if nGrp and nPrc and nDo == 1 then + local Proc = {} + Proc.PartId = PartId + Proc.Id = ProcId + Proc.Grp = nGrp + Proc.Prc = nPrc + Proc.Flg = 1 + Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0 + Proc.Diam = 0 + Proc.Fcs = 0 + Proc.Fce = 0 + Proc.CutId = nCutId + Proc.TaskId = nTaskId + Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) + if Proc.Box and not Proc.Box:isEmpty() then + if Drill.Identify( Proc) then + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + end + table.insert( vProc, Proc) + else + EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)') + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw) + for i = 1, #vProc do + local Proc = vProc[i] + -- se foratura + if Drill.Identify( Proc) then + local bOk = Drill.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se contorno libero, outile o aperture + elseif FreeContour.Identify( Proc) then + local bOk = FreeContour.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc) + EgtOutLog( ' *** Feature List ***') + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Part=%3d Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', + Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nRawId, b3Raw) + local bOk = true + local sErr = '' + -- se foratura ( 3/4-040-X) + if Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nRawId, b3Raw) + -- se contorno libero, outline o apertura ( 0/3/4-250/251/252-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nRawId, b3Raw) + end + return bOk, sErr +end + +------------------------------------------------------------------------------------------------------------- +function WallExec.ProcessFeatures() + -- errori e stato + local nTotErr = 0 + local Stats = {} + -- recupero il grezzo e il suo box + local nRawId = EgtGetFirstRawPart() + local b3Raw = EgtGetRawPartBBox( nRawId) + -- raccolgo l'elenco delle feature da lavorare, ciclando sui pezzi + local vProc = {} + local nPartId = EgtGetFirstPartInRawPart( nRawId) + while nPartId do + -- recupero le feature di lavorazione della parete + local vPartProc = CollectFeatures( nPartId, b3Raw) + vProc = EgtJoinTables( vProc, vPartProc) + nPartId = EgtGetNextPartInRawPart( nPartId) + end + -- classifico le feature + ClassifyFeatures( vProc, b3Raw) + -- ordino le feature + -- *** TODO *** + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc) + end + -- inserisco le lavorazioni + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 then + local bOk, sMsg = AddFeatureMachining( Proc, nRawId, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + end + -- restituzione risultati + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return WallExec diff --git a/Process.lua b/Process.lua index b0a0224..bb7432c 100644 --- a/Process.lua +++ b/Process.lua @@ -1,4 +1,4 @@ --- Process.lua by Egaltech s.r.l. 2020/04/06 +-- Process.lua by Egaltech s.r.l. 2020/04/25 -- Gestione calcolo disposizione e lavorazioni per Pareti -- Si opera sulla macchina corrente @@ -30,8 +30,8 @@ EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') EgtOutLog( '*** Wall Process Start ***', 1) -- Carico le librerie ---_G.package.loaded.BeamExec = nil ---local BE = require( 'BeamExec') +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') --local BL = require( 'BeamLib') -- Carico i dati globali @@ -76,7 +76,7 @@ local function MyProcessInputData() EgtOutLog( 'Pareti selezionate : ' .. sOut, 1) end - -- Ne recupero e verifico le dimensioni + -- Ne recupero le dimensioni for i = 1, #vWall do local Ls = EgtGetFirstNameInGroup( vWall[i].Id, 'Box') local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) @@ -87,6 +87,37 @@ local function MyProcessInputData() vWall[i].Box = b3Solid end end + + -- Ne recupero la posizione + local CurrX = 100 + for i = 1, #vWall do + local PosX = EgtGetInfo( vWall[i].Id, 'POSX', 'd') + if not PosX then PosX = CurrX end + vWall[i].PosX = PosX + CurrX = CurrX + vWall[i].Box:getDimX() + 50 + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') or 100 + vWall[i].PosZ = PosZ + end + + -- Eseguo eventuali rotazioni e inversioni testa-coda + for i = 1, #vWall do + local b3Solid = vWall[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vWall[i].Id, 'ROTATED', 'd') or 0 + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') or 180) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end + end + + -- Ne verifico le dimensioni dRawH = vWall[1].Box:getDimZ() local vWallErr = {} for i = 2, #vWall do @@ -117,28 +148,27 @@ end ------------------------------------------------------------------------------------------------------------- local function MyProcessWalls() - -- Lunghezza totale delle pareti - local dTotLen = 0 - for i = 1, #vWall - 1 do - dTotLen = dTotLen + vWall[i].Box:getDimX() - end - dTotLen = dTotLen + max( vWall[#vWall].Box:getDimX(), WD.MIN_LENGTH) - local dAddLen = WD.OVM_HEAD + ( #vWall - 1) * WD.OVM_MID - EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) - - -- Larghezza massima delle pareti - local dMaxWid = 0 + -- Ingombro totale delle pareti + local b3Tot = BBox3d( ORIG()) for i = 1, #vWall do - if vWall[i].Box:getDimY() > dMaxWid then - dMaxWid = dMaxWid + vWall[i].Box:getDimY() - end + local ptMin = Point3d( - vWall[i].PosX - vWall[i].Box:getDimX(), vWall[i].PosZ, 0) + local ptMax = Point3d( - vWall[i].PosX, vWall[i].PosZ + vWall[i].Box:getDimY(), 0) + b3Tot:Add( ptMin) + b3Tot:Add( ptMax) end + local dBoxL = b3Tot:getDimX() + local dBoxW = b3Tot:getDimY() + EgtOutLog( 'Ltot : ' .. EgtNumToString( dBoxL, 1) .. ' Wtot : '.. EgtNumToString( dBoxW, 1), 1) + + -- Eventuali dimensioni predefinite del pannello + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL + local dPanelLen = EgtGetInfo( BtlInfoId, 'PANELLEN', 'd') or WD.STD_RAW_LENGTH + local dPanelWidth = EgtGetInfo( BtlInfoId, 'PANELWIDTH', 'd') or WD.STD_RAW_WIDTH -- Richiedo lunghezza del grezzo e sovramateriale di testa - local vsVal = EgtDialogBox( 'Lavora Pareti' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Wmax=' .. EgtNumToString( dMaxWid + 0.5, 0) .. ')', - {'Lunghezza grezzo', EgtNumToString( WD.STD_RAW_LENGTH, 0)}, - {'Larghezza grezzo', EgtNumToString( WD.STD_RAW_WIDTH, 0)}, - {'Sovramateriale', EgtNumToString( WD.OVM_HEAD, 0)}) + local vsVal = EgtDialogBox( 'Lavora Pareti' .. ' (Ltot='.. EgtNumToString( dBoxL + 0.5, 0) .. ', Wtot=' .. EgtNumToString( dBoxW + 0.5, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( dPanelLen, 0)}, + {'Larghezza grezzo', EgtNumToString( dPanelWidth, 0)}) if not vsVal then EgtDraw() return @@ -161,14 +191,6 @@ local function MyProcessWalls() return false end dRawW = min( dRawW, WD.MAX_WIDTH ) - local dOvmHead = EgtEvalNumExpr( vsVal[3]) - if not dOvmHead then - local sOut = 'Sovramateriale di testa errato : ' .. vsVal[3] - EgtOutLog( sOut) - EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') - EgtDraw() - return false - end -- Verifico dimensioni massime grezzo if dRawL > WD.MAX_LENGTH + 10 * GEO.EPS_SMALL or dRawW > WD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > WD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then @@ -191,60 +213,7 @@ local function MyProcessWalls() end -- Sistemo le pareti nel grezzo - -- Creazione nuovo gruppo di lavoro - local sMgName = EgtGetMachGroupNewName( 'Mach') - local NewMgId = EgtAddMachGroup( sMgName) - if not NewMgId then - local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName - return false, sOut - end - -- Impostazione della tavola - EgtSetTable( 'Tab') - -- Area tavola - local b3Tab = EgtGetTableArea() - -- Calcolo posizione estremo TR della tavola rispetto a sua origine in BL - WD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) - -- Impostazione dell'attrezzaggio di default - EgtImportSetup() - -- Creazione del grezzo e suo posizionamento in macchina - local nRaw = EgtAddRawPart( Point3d(0,0,0), dRawL, dRawW, dRawH, WD.RAWCOL) - EgtMoveToCornerRawPart( nRaw, WD.OriTR, MCH_CR.TR) - -- Inserimento dei pezzi nel grezzo - local Cnt = 0 - local Len = dRawL - local DeltaS = dOvmHead - local DeltaE = WD.OVM_MID - for i = 1, #vWall do - -- assegno identificativo pezzo - local Pz = vWall[i].Id - -- dati del pezzo - local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) - local b3Solid = vWall[i].Box - if b3Part:isEmpty() or b3Solid:isEmpty() then break end - -- se spessore compatibile e lunghezza disponibile sufficiente - local PartLen = b3Solid:getDimX() - local PartWidth = b3Solid:getDimY() - local PartHeight = b3Solid:getDimZ() - local NextLen = Len - DeltaS - PartLen - DeltaE - if ( dRawW > PartWidth - 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) and NextLen + DeltaE >= 0 then - -- eventuale sovramateriale di testa - if vWall[i].PosX then - DeltaS = max( vWall[i].PosX - ( dRawL - Len), 0) - end - -- dimensioni del grezzo - local CrawLen = min( PartLen + DeltaS + DeltaE, Len) - local Delta = Len - PartLen - DeltaS - -- inserisco il pezzo nel grezzo - EgtDeselectPartObjs( Pz) - local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, dRawW - PartWidth - dOvmHead, ( dRawH - PartHeight) / 2) - EgtAddPartToRawPart( Pz, ptPos, nRaw) - -- aggiorno la lunghezza residua della barra - Len = Len - CrawLen - end - DeltaS = 0 - end - - return true + return WE.ProcessWalls( dRawL, dRawW, dRawH, vWall) end ------------------------------------------------------------------------------------------------------------- @@ -252,7 +221,7 @@ end ------------------------------------------------------------------------------------------------------------- local function MyProcessFeatures() - local bOk, Stats = BE.ProcessFeatures() + local bOk, Stats = WE.ProcessFeatures() local nErrCnt = 0 local nWarnCnt = 0 local sOutput = '' @@ -289,4 +258,4 @@ if not MyProcessWalls() then return end -- Abilito Vmill EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') ---if not MyProcessFeatures() then return end +if not MyProcessFeatures() then return end